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

EF Core 7.0中如何用Database.SqlQuery<T>映射自定义对象?

EF Core 7.0 SqlQuery 映射到自定义对象的实现方法

EF Core 7.0的DatabaseFacade.SqlQuery<T>完全支持将自定义SQL查询的结果映射到非数据库模型的自定义POCO对象,官方文档提到的“仅支持数据库原生标量类型”是基础场景描述,通过以下方式可实现自定义对象的映射:

1. 基础场景:属性与查询列名一致

如果自定义类的属性名称和SQL查询返回的列名完全匹配(大小写规则取决于数据库,比如SQL Server不区分大小写,PostgreSQL区分),无需额外配置即可直接映射。

示例代码

先定义自定义结果类:

public class BookSearchResult
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string AuthorName { get; set; }
    public decimal Rating { get; set; }
}

执行自定义SQL查询:

var query = @"
    SELECT Id, Title, AuthorName, Rating 
    FROM Books 
    WHERE PublicationYear > @year";

var searchResults = context.Database
    .SqlQuery<BookSearchResult>(query, new SqlParameter("@year", 2020))
    .ToList();

2. 列名与属性名不一致:两种解决方式

如果查询返回的列名和自定义类的属性名不匹配,可通过以下方式处理:

方式一:使用[Column]特性

直接在自定义类的属性上标注对应的数据库列名:

public class BookSearchResult
{
    [Column("book_id")]
    public int Id { get; set; }
    
    [Column("book_title")]
    public string Title { get; set; }
    
    public string AuthorName { get; set; }
}

方式二:在DbContext中配置无键实体映射

如果需要复杂映射规则(比如类型转换、默认值设置),可在OnModelCreating中将自定义类配置为无键实体:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<BookSearchResult>(entity =>
    {
        entity.HasNoKey(); // 标记为无键实体,无需主键
        entity.Property(e => e.Id).HasColumnName("book_id");
        entity.Property(e => e.Title).HasColumnName("book_title");
        // 示例:将数据库int类型映射为自定义枚举
        entity.Property(e => e.BookType)
              .HasConversion<string>()
              .HasColumnName("book_type");
    });
}

注意事项

  • 自定义类不需要添加到DbContext的DbSet中,只要属性匹配或配置了无键实体即可使用
  • SQL查询返回的列若没有对应属性,EF Core会自动忽略;类的属性若没有对应列,会被设置为类型默认值(如null、0)
  • 对于复杂类型转换(比如JSON列映射到.NET对象),可结合ValueConverter在模型配置中实现

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 10:05:08