无DbSet时调用返回无主键数据集的存储过程并返回自定义模型列表
调用无主键返回结果的存储过程并返回自定义模型列表
针对你遇到的问题——没有对应DbSet但需要调用返回无主键数据集的存储过程,这里有两种实用的解决方案:
方法一:使用EF Core的无键实体类型(推荐)
这是EF Core官方专门针对这类无主键查询场景设计的方案,操作起来简洁规范:
- 定义自定义模型类
先创建和存储过程返回字段完全匹配的模型类,属性名称、类型要和存储过程的输出字段保持一致(比如SQL Server默认不区分大小写,但尽量统一避免映射错误):
public class BankDataResult { public int BankDataId { get; set; } public string BankName { get; set; } // 补充存储过程返回的其他字段对应的属性 }
- 在DbContext中配置无键实体
有两种配置方式二选一即可:
- 特性标记法:直接在模型类上添加
[Keyless]特性[Keyless] public class BankDataResult { ... } - Fluent API法:在DbContext的
OnModelCreating方法里配置protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<BankDataResult>().HasNoKey(); }
- 调用存储过程并获取结果
现在就可以通过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
相关产品推荐
相关产品推荐

