如何在ASP.NET Core 6中使用EF Core执行SQL Server标量函数
在ASP.NET Core 6中执行SQL Server标量函数的可行方法
原代码存在的问题
- 无需用
Task.Run包裹EF Core查询:EF Core的异步方法本身是非阻塞的,额外包裹会造成不必要的线程开销 - 错误使用
.Result阻塞异步调用:在异步方法中调用.Result容易引发死锁,应改用await - 属性拼写错误:
Describtion应为Description - 实体映射不匹配:如果
OcrDictInfos实体类没有Description属性,直接查询会导致映射失败
方法一:修正FromSqlRaw查询(适合快速调整)
如果不想修改DbContext配置,可以通过DTO接收查询结果,修正异步调用逻辑:
- 先定义一个DTO类来接收包含标量函数结果的数据:
public class OcrDictResult { public int Id { get; set; } public string Keyword { get; set; } public string Description { get; set; } }
- 改写查询代码:
var sqlQuery = "SELECT TOP(1) Id, Keyword, dbo.ProcessWords({0}) AS Description FROM Info"; var queryResult = await administrationDbContext.Set<OcrDictResult>() .FromSqlRaw(sqlQuery, myText) .FirstOrDefaultAsync(); // 处理可能的null情况 return queryResult?.Description;
方法二:EF Core标量函数映射(类型安全,推荐)
通过EF Core的函数映射功能,直接在LINQ查询中调用标量函数,更符合EF Core的使用规范:
- 在你的DbContext类中添加函数映射(注意是静态方法):
public class AdministrationDbContext : DbContext { // 其他DbSet和配置... [DbFunction("ProcessWords", Schema = "dbo")] public static string ProcessWords(string input) { // 仅用于映射,无需实现具体逻辑 throw new NotImplementedException(); } protected override void OnModelCreating(ModelBuilder modelBuilder) { // 可选:显式配置函数映射(确保和数据库函数名称、Schema一致) modelBuilder.HasDbFunction(typeof(AdministrationDbContext).GetMethod(nameof(ProcessWords))) .HasName("ProcessWords") .HasSchema("dbo"); } }
- 在查询中直接调用映射的函数:
var queryResult = await administrationDbContext.Info .Select(info => new OcrDictResult { Id = info.Id, Keyword = info.Keyword, Description = AdministrationDbContext.ProcessWords(myText) }) .FirstOrDefaultAsync(); return queryResult?.Description;
内容的提问来源于stack exchange,提问作者Altan
相关产品推荐
相关产品推荐

