如何通过DTO从存储过程获取非实体数据?EF调用问题求解
正确调用存储过程获取数据的方式
根据你使用的Entity Framework版本,以下是对应的解决方案:
情况1:使用EF Core 5.0及以上版本
EF Core 5.0开始支持直接通过Database.SqlQuery<T>查询无实体映射的DTO,直接修改调用代码即可:
var result = await _context.Database.SqlQuery<CummGraphDTO>("exec dbo.GetCummulative").ToListAsync();
情况2:使用EF Core 3.x及更早版本
这类版本不支持直接查询无实体DTO,需要先在DbContext中注册DTO的虚拟集合:
- 在你的
DbContext类中添加DTO的DbSet,并标记为无主键(避免EF尝试生成数据库表):
public class YourDbContext : DbContext { // 其他已有的DbSet定义... public DbSet<CummGraphDTO> CummGraphDTOs { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<CummGraphDTO>().HasNoKey(); } }
- 使用
FromSqlRaw调用存储过程:
var result = await _context.CummGraphDTOs.FromSqlRaw("exec dbo.GetCummulative").ToListAsync();
情况3:使用EF6
如果原代码无法工作,可尝试通过ObjectContext执行查询:
var objectContext = ((IObjectContextAdapter)_context).ObjectContext; var result = await objectContext.ExecuteStoreQuery<CummGraphDTO>("exec dbo.GetCummulative").ToListAsync();
额外检查项
- 确认存储过程返回的列名(
Datex、Score)与DTO的属性名完全匹配(大小写不敏感,但需避免拼写错误) - 确保DTO的属性类型与存储过程返回的列类型一致:
Datex对应DateTime,Score对应int/int? - 如果存储过程需要参数,需正确传递,示例:
var param = new SqlParameter("@ParamName", paramValue); var result = await _context.Database.SqlQuery<CummGraphDTO>("exec dbo.GetCummulative @ParamName", param).ToListAsync();
内容的提问来源于stack exchange,提问作者dave_bell
相关产品推荐
相关产品推荐

