EF Core 6.0如何编写原生SQL查询调用未脚手架生成的数据库函数?
EF Core 6 调用SQL Server原生函数/自定义SQL实现方法
你现有的NuGet包依赖、环境配置已经完全满足原生SQL查询、数据库函数调用的要求,不需要额外安装组件或修改配置,可直接按以下场景选择实现方式:
方式一:映射数据库函数到LINQ(推荐,复用性最高)
脚手架工具不会自动生成独立的用户自定义函数映射,你可以通过partial类扩展自动生成的DbContext,避免后续重新执行脚手架命令覆盖自定义代码:
- 新建和自动生成的DbContext类同名的partial类(比如自动生成的上下文类名为
MyDbContext,就新建同名文件写partial定义) - 在类中添加对应数据库函数的映射桩方法,示例:
public partial class MyDbContext { /// <summary> /// 映射SQL Server中的dbo.xxx标量函数 /// </summary> /// <param name="inputParam">和数据库函数定义的参数类型、顺序保持一致</param> /// <returns>和数据库函数返回值类型匹配</returns> [DbFunction("你的数据库函数名", "dbo")] public static int? MyCustomScalarFunction(string inputParam) { // 方法不需要实现,仅作为LINQ调用的标记,EF Core会自动翻译为SQL throw new NotSupportedException("Direct calls to this method are not supported, it is only for LINQ translation."); } }
配置完成后,你可以直接在任意LINQ查询中调用这个静态方法,EF Core会自动将其翻译为对应的数据库函数调用,在数据库端执行。
方式二:直接执行原生SQL语句
如果你不需要长期复用函数映射,也可以直接用EF Core内置的原生SQL执行接口:
- 场景1:调用标量函数返回单个值
// 务必使用参数化传值,禁止直接拼接用户输入到SQL字符串避免注入风险 var myParam = new SqlParameter("@input", "测试参数"); var result = await dbContext.Database .SqlQueryRaw<int?>("SELECT dbo.你的函数名(@input)", myParam) .FirstOrDefaultAsync();
- 场景2:调用表值函数返回实体集合
var myParam = new SqlParameter("@queryId", 123); var resultList = await dbContext.对应实体的DbSet .FromSqlRaw("SELECT * FROM dbo.你的表值函数名(@queryId)", myParam) .ToListAsync();
- 场景3:执行无返回值的存储过程/函数
var param1 = new SqlParameter("@id", 456); await dbContext.Database.ExecuteSqlRawAsync("EXEC dbo.你的存储过程名 @id", param1);
注意事项
- 所有原生SQL执行场景都要使用参数化传值,不要直接把变量拼接到SQL字符串中,避免SQL注入漏洞。
- 所有自定义的EF Core配置、函数映射都写在独立的partial类文件中,不要修改脚手架自动生成的代码文件,否则下次执行scaffold命令时自定义内容会被覆盖。
- 你贴出的NuGet包引用中
Microsoft.EntityFrameworkCore.Design和Microsoft.EntityFrameworkCore.Tools两个包的引用标签未闭合,只要脚手架命令能正常运行就不影响功能,后续修改csproj时补全闭合标签即可。
内容的提问来源于stack exchange,提问作者Aj.son
相关产品推荐
相关产品推荐

