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

无DbSet时调用返回无主键数据集的存储过程并返回自定义模型列表

调用无主键返回结果的存储过程并返回自定义模型列表

针对你遇到的问题——没有对应DbSet但需要调用返回无主键数据集的存储过程,这里有两种实用的解决方案:

方法一:使用EF Core的无键实体类型(推荐)

这是EF Core官方专门针对这类无主键查询场景设计的方案,操作起来简洁规范:

  1. 定义自定义模型类
    先创建和存储过程返回字段完全匹配的模型类,属性名称、类型要和存储过程的输出字段保持一致(比如SQL Server默认不区分大小写,但尽量统一避免映射错误):
public class BankDataResult
{
    public int BankDataId { get; set; }
    public string BankName { get; set; }
    // 补充存储过程返回的其他字段对应的属性
}
  1. 在DbContext中配置无键实体
    有两种配置方式二选一即可:
  • 特性标记法:直接在模型类上添加[Keyless]特性
    [Keyless]
    public class BankDataResult { ... }
    
  • Fluent API法:在DbContext的OnModelCreating方法里配置
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<BankDataResult>().HasNoKey();
    }
    
  1. 调用存储过程并获取结果
    现在就可以通过context.Set<BankDataResult>()来执行存储过程,拿到自定义模型列表了:
var bankDataParam = new SqlParameter("@BankDataId", targetBankDataId);
var resultList = await context.Set<BankDataResult>()
                              .FromSqlRaw("EXEC [xxx].[VF_Set_PrimaryXXX] @BankDataId", bankDataParam)
                              .ToListAsync();

方法二:直接使用ADO.NET原生方式

如果不想在DbContext里添加实体配置,也可以用原生ADO.NET直接执行存储过程并手动映射结果:

var resultList = new List<BankDataResult>();
var bankDataParam = new SqlParameter("@BankDataId", targetBankDataId);

using (var connection = this.Database.GetDbConnection())
{
    await connection.OpenAsync();
    using (var command = connection.CreateCommand())
    {
        command.CommandText = "[xxx].[VF_Set_PrimaryXXX]";
        command.CommandType = CommandType.StoredProcedure;
        command.Parameters.Add(bankDataParam);

        using (var reader = await command.ExecuteReaderAsync())
        {
            while (await reader.ReadAsync())
            {
                var model = new BankDataResult
                {
                    BankDataId = reader.GetInt32(reader.GetOrdinal("BankDataId")),
                    BankName = reader.GetString(reader.GetOrdinal("BankName")),
                    // 依次映射其他属性
                };
                resultList.Add(model);
            }
        }
    }
}
// resultList就是最终需要的自定义模型列表

注意事项

  • 两种方法都一定要用SqlParameter传递参数,绝对不能直接拼接参数值,避免SQL注入风险。
  • 如果存储过程有多个参数,只需要添加对应的SqlParameter实例即可。

内容的提问来源于stack exchange,提问作者Thomas Segato

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 20:33:11