You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在EntityFrameworkCore 2中使用.FromSql执行存储过程的实现问题

在EF Core 2.x中调用SQL Server存储过程的完整实现

我来帮你补全这个方法,并且把关键细节说清楚——EF Core 2.x调用返回实体列表的存储过程其实很直接,主要用FromSql方法就可以搞定:

完整的方法代码

public IList<Trader> GetTradersWithinRadius(int category, decimal latitude, decimal longitude) {
    var sproc = "FindTradersWithinRadius";
    var sqlParams = new List<SqlParameter>() {
        new SqlParameter("@CATEGORY", category),
        new SqlParameter("@LATITUDE", latitude),
        new SqlParameter("@LONGITUDE", longitude),
    };
    
    // 调用存储过程并映射到Trader实体列表
    return this.Traders
        .FromSql($"{sproc} @CATEGORY, @LATITUDE, @LONGITUDE", sqlParams.ToArray())
        .ToList();
}

关键细节说明

  • FromSql的作用:这个方法允许你直接执行原生SQL(包括存储过程),并将结果映射到DbSet<T>对应的实体类型。这里我们传入存储过程名称和预先定义的SqlParameter数组,既保证了可读性,又避免了SQL注入风险。
  • 参数传递:你手动创建SqlParameter的方式非常安全,EF Core会自动处理参数绑定,不需要你手动拼接SQL字符串。
  • 实体映射要求:
    • 你的Trader实体必须在DbContext中注册为DbSet<Trader>(也就是this.Traders)。
    • 存储过程返回的结果集列名必须和Trader实体的属性名匹配(SQL Server默认大小写不敏感,但最好保持一致)。如果列名和属性名不匹配,可以在实体属性上添加[Column("存储过程列名")]特性来做映射。

可选的简化写法

如果你不想手动创建SqlParameter,也可以用占位符的方式让EF Core自动帮你生成参数,代码会更简洁:

public IList<Trader> GetTradersWithinRadius(int category, decimal latitude, decimal longitude) {
    return this.Traders
        .FromSql("EXEC FindTradersWithinRadius @CATEGORY = {0}, @LATITUDE = {1}, @LONGITUDE = {2}", category, latitude, longitude)
        .ToList();
}

特殊情况处理

如果你的存储过程返回的不是完整的Trader实体字段,而是自定义的结果集,那么你需要创建一个DTO类,然后用context.Query<CustomDto>().FromSql(...)来映射——不过要记得先安装Microsoft.EntityFrameworkCore.Relational包,Query<T>方法在这个包里。

内容的提问来源于stack exchange,提问作者Matthew Flynn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 02:30:07