在.NET6数据库优先模式下,如何简便调用返回多表列的存储过程?
.NET6 调用无对应实体的存储过程简便方案
方法1:使用Dapper(推荐)
Dapper是轻量级ORM,语法简洁,完美适配这种返回非实体结构的存储过程调用场景。
- 先通过NuGet安装
Dapper包 - 定义与存储过程返回列匹配的DTO类(列名大小写不敏感):
public class MyDataDto { public int Id { get; set; } public string Name { get; set; } public decimal Amount { get; set; } public DateTime CreateTime { get; set; } public string Category { get; set; } } - 调用存储过程,直接复用EF上下文的数据库连接:
using var connection = context.Database.GetDbConnection(); var result = await connection.QueryAsync<MyDataDto>("GetMyData", commandType: CommandType.StoredProcedure);
方法2:自定义EF Core扩展实现SqlQuery
如果不想引入第三方库,可以自己实现一个扩展方法,模拟EF Core后续版本的SqlQuery功能:
- 扩展方法代码:
public static class DbContextExtensions { public static async Task<List<T>> SqlQueryAsync<T>(this DbContext context, string sql, params object[] parameters) where T : class { using var command = context.Database.GetDbConnection().CreateCommand(); command.CommandText = sql; command.CommandType = CommandType.StoredProcedure; if (context.Database.CurrentTransaction != null) { command.Transaction = context.Database.CurrentTransaction.GetDbTransaction(); } foreach (var parameter in parameters) { command.Parameters.Add(parameter); } await context.Database.OpenConnectionAsync(); using var reader = await command.ExecuteReaderAsync(); var list = new List<T>(); var props = typeof(T).GetProperties().ToList(); while (await reader.ReadAsync()) { var entity = Activator.CreateInstance<T>(); foreach (var prop in props) { if (!reader.IsDBNull(reader.GetOrdinal(prop.Name))) { prop.SetValue(entity, reader[prop.Name]); } } list.Add(entity); } return list; } } - 调用方式:
var result = await context.SqlQueryAsync<MyDataDto>("GetMyData");
方法3:使用EF Core无键实体
如果愿意在EF上下文中注册临时实体,可采用原生EF Core方案:
- 定义无键DTO,并在上下文配置:
public class MyDataDto { public int Id { get; set; } public string Name { get; set; } public decimal Amount { get; set; } public DateTime CreateTime { get; set; } public string Category { get; set; } } // 在DbContext的OnModelCreating方法中配置 protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<MyDataDto>().HasNoKey(); } - 调用存储过程:
var result = await context.Set<MyDataDto>().FromSqlRaw("EXEC GetMyData").ToListAsync();
内容的提问来源于stack exchange,提问作者coolblue2000
相关产品推荐
相关产品推荐

