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

在.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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 21:15:10