使用 Entity Framework Core (2.1) 调用标量函数的最佳实践
Posted
技术标签:
【中文标题】使用 Entity Framework Core (2.1) 调用标量函数的最佳实践【英文标题】:Best practice calling scalar functions with Entity Framework Core (2.1) 【发布时间】:2018-12-11 14:27:30 【问题描述】:我经常需要从我的 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")
通过使用这种模式,我可以以相同的方式调用任意数量的函数,而无需定义其他类型或扩展上下文类。
如果我可以通过这种模式陷入陷阱,请告诉我。非常感谢。
【问题讨论】:
我看不出它有什么大问题,但是您可以稍微重构一下,这样您就不必在每次调用时都提供整个查询。在上下文中创建一个属性,该属性为每个函数/过程返回一个BasicDto<int>
,例如,它接受所需的任何参数。
你是对的 - 感谢这个想法。
你为什么不使用Database scalar function mapping。是的,它需要您扩展上下文类,但不需要其他类型,并提供可重用性、智能感知支持和编译时检查,就像常规 LINQ 和 CLR 方法一样。
感谢 Ivan Stoev 的提示 - 我必须承认我还不知道这个功能。但事实证明你不能通过这个特性直接调用标量函数——你必须从一个实体类型开始,然后可以在查询中使用这些方法存根(即 context.ENTITY.where(x => x.METHODSTUB()) ...)。然而,他们似乎正在努力解决这个问题(参见github.com/aspnet/EntityFrameworkCore/issues/9810)。再次感谢您指出这一点。
看起来像DbQuery is deprecated for EF Core 3,所以应该是DbSet<PrimitiveDto<int>>
。
【参考方案1】:
不幸的是,这个功能似乎被搁置了: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);
【讨论】:
我喜欢这种方法,并将其用于替代解决方案:***.com/a/68902584/6680521以上是关于使用 Entity Framework Core (2.1) 调用标量函数的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章
在 Entity Framework Core 中使用 [ComplexType]
在 Entity Framework Core 中使用 SQL 视图
使用 Entity Framework Core 更新相关数据