ASP.NET Core MVC中无对应Model时如何执行Raw SQL并生成自定义Model
ASP.NET Core 5 MVC 无预定义Model执行原生SQL并映射到自定义Model的实现方案
方案1:使用EF Core无键实体(推荐,适配EF Core生态)
不用让Model绑定实际数据库表,仅做查询结果映射即可,步骤如下:
- 先定义和SQL返回字段匹配的自定义Model:
public class TeacherQueryResult { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } }
- 在你的
mfdDbContext对应的上下文类中,配置该Model为无键实体:
protected override void OnModelCreating(ModelBuilder modelBuilder) { // 其他现有配置... modelBuilder.Entity<TeacherQueryResult>().HasNoKey(); }
- 直接执行原生SQL查询映射到自定义Model:
var results = mfdDbContext.Set<TeacherQueryResult>() .FromSqlRaw("select id, firstName, lastName from teachers order by id desc") .ToList();
方案2:基于ADO.NET直接读取映射(无需修改DbContext配置)
如果不想改动现有DbContext的配置,可以直接从EF Core上下文拿数据库连接,用原生ADO.NET读取数据后手动映射到自定义Model:
- 先定义和方案1一致的
TeacherQueryResult自定义Model - 执行查询并映射:
var results = new List<TeacherQueryResult>(); var connection = mfdDbContext.Database.GetDbConnection(); try { await connection.OpenAsync(); using var command = connection.CreateCommand(); command.CommandText = "select id, firstName, lastName from teachers order by id desc"; using var reader = await command.ExecuteReaderAsync(); while (await reader.ReadAsync()) { results.Add(new TeacherQueryResult { Id = reader.GetInt32(reader.GetOrdinal("id")), FirstName = reader.IsDBNull(reader.GetOrdinal("firstName")) ? null : reader.GetString(reader.GetOrdinal("firstName")), LastName = reader.IsDBNull(reader.GetOrdinal("lastName")) ? null : reader.GetString(reader.GetOrdinal("lastName")) }); } } finally { await connection.CloseAsync(); }
注意事项
- 方案1支持叠加EF Core的链式查询方法(如
Where、Skip、Take),适合多次复用该查询结构的场景 - 两种方案都需要确保SQL返回的字段名和自定义Model的属性名对应,不匹配时可以在SQL中给字段加别名适配
内容的提问来源于stack exchange,提问作者midowu
相关产品推荐
相关产品推荐

