使用实体框架核心 (2.1) 调用标量函数的最佳做法



我经常需要从我的 Web 应用程序(ASP.NET Core/EF Core(调用在 SQL Server 上定义的标量函数。由于这些函数只是简单的帮助程序函数,并且我也使用了很多函数,因此我使用常规模式来调用这些标量函数 - 借助 EF Core 2.1 中提供的新查询类型。 由于我对 EF Core 相对较新,因此我的问题是此模式是否会导致问题和/或是否有更好的解决方案或最佳做法来调用标量函数。该解决方案有效,到目前为止我无法观察到任何问题,但例如,我想知道对不同的函数使用相同的查询类型是否会导致意外值或由于 EF Core 中的缓存/跟踪行为等而导致奇怪的行为 - 这更像是一种直觉。

所以这是模式: 我不是为每个标量函数定义不同的实体类型,而是简单地定义一个泛型类型:

public class PrimitiveDto<T>
{
public T Value { get; set; }
}

在我的上下文类中,我为我期望从我要使用的标量函数中获得的每个返回类型注册这些类型 - 因此对于所有返回"int"的标量函数,上下文类将有一个额外的条目,如下所示:

public virtual DbQuery<PrimitiveDto<int>> BasicIntDto { get; set; }

对于 EF Core>= 3,它是:

public virtual DbSet<PrimitiveDto<int>> BasicIntDto { get; set; }

在我想调用返回 'int' 的标量函数的应用程序的每个部分中,我只需使用相同的以下模式:

context.BasicIntDto.FromSql("SELECT <FUNCTION> AS Value")

通过使用此模式,我可以以相同的方式调用任意数量的函数,而无需定义其他类型或扩展上下文类。

请让我知道我是否可以通过这种模式遇到陷阱。谢谢。

不幸的是,这个功能似乎被搁置一旁:https://github.com/aspnet/EntityFrameworkCore/issues/9810

一个选项是使用一个永不为空的小表将函数调用包装在静态类中:

public static class DbFunctions
{
public static decimal MyFunctionABC(int param1, int param2)
{
using (var db = new MyDbContext())
{
return db.table.Take(1).Select(t => MyDbContext.MyFunctionABC(x, y)).Single();
}
}
}

然后你可以打电话DbFunctions.MyFunctionABC(x,y);

最新更新