如何通过EF Core Power Tools正确调用SQL Server数据库函数
EF Core Power Tools 加载调用SQL Server数据库函数方案
生成代码中函数直接抛出NotSupportedException不是工具生成错误,是EF Core数据库函数映射的默认设计逻辑:映射的数据库函数仅支持在LINQ to Entities查询中被翻译成SQL执行,不支持脱离查询上下文直接作为普通C#方法调用。
一、确认Power Tools生成配置正确
- 执行反向工程操作时,在数据库对象选择界面,除了表、存储过程,同步勾选需要导入的标量函数、表值函数
- 确认生成设置中开启了DbFunction特性映射,你贴出的带
[DbFunction]标记的静态方法就是正确的生成结果,不需要你额外手动添加同名方法、重复配置HasDbFunction映射,你之前自行添加的实例方法、重复FluentAPI配置反而可能引发映射冲突,建议删除。 - 生成代码中空的
OnModelCreatingGeneratedFunctions分部方法是正常预留点位,使用特性映射的函数不需要在这里额外写配置。
二、标准调用方法
1. 查询场景调用(官方推荐用法)
直接在EF Core的LINQ查询表达式中调用生成的静态函数即可,EF Core会自动将其翻译为对应的数据库函数语法,在数据库侧执行,不会触发异常:
var result = (from customer in context.Customers join article in context.Articles on customer.Id equals article.CustomerId select new { CustomerId = customer.Id, ArticleId = article.Id, USTText = ZentralContext.GET_UST_Text(customer.Id, article.Id), USTSatz = ZentralContext.GET_UST_Satz(customer.Id, article.Id) }).ToList();
上述代码会被翻译为类似如下的SQL语句执行:
SELECT c.Id AS CustomerId, a.Id AS ArticleId, dbo.GET_UST_Text(c.Id, a.Id) AS USTText, dbo.GET_UST_Satz(c.Id, a.Id) AS USTSatz FROM Customers c INNER JOIN Articles a ON c.Id = a.CustomerId
2. 单独调用函数取返回值
如果不需要关联表查询,只是想直接传入参数获取函数返回值,使用EF Core原生的原始查询接口包装调用即可:
int? inputCustomerId = 1001; int? inputArticleId = 2003; // 调用字符串返回值函数 string ustText = context.Database .SqlQueryRaw<string>("SELECT dbo.GET_UST_Text({0}, {1})", inputCustomerId, inputArticleId) .AsEnumerable() .First(); // 调用数值返回值函数 double? ustSatz = context.Database .SqlQueryRaw<double?>("SELECT dbo.GET_UST_Satz({0}, {1})", inputCustomerId, inputArticleId) .AsEnumerable() .First();
三、注意事项
- 不要直接在LINQ查询外像普通静态方法一样调用生成的函数,这种场景下EF Core无法翻译函数为SQL,必然会抛出
NotSupportedException - 注意参数类型匹配:生成的函数参数为可空值类型
int?,传入非空int类型参数时可以自动隐式转换,不需要强行修改生成的方法签名 - 如果你使用的是较旧版本的EF Core Power Tools,升级到最新版本后重新反向工程生成代码,即可自动完成所有函数映射配置,不需要手动修改DbContext
内容的提问来源于stack exchange,提问作者flomue99
相关产品推荐
相关产品推荐

