调用SqlQuery<T>遇类型不支持异常,配置DefaultTypeMapping仍未解决
问题排查与解决方案
你遇到的问题核心在于:ModelConfigurationBuilder.DefaultTypeMapping是用来配置标量类型(比如自定义值类型)的数据库映射,而EmployeeInfo是包含多属性的复杂DTO类,这个配置完全不适用,自然解决不了问题。
要让EF Core识别EmployeeInfo并支持SqlQuery<T>查询,正确的做法是将EmployeeInfo配置为无键实体(Keyless Entity),具体步骤如下:
1. 修改DbContext的OnModelCreating方法
在OnModelCreating中添加EmployeeInfo的无键实体配置,替换掉原来无效的DefaultTypeMapping配置:
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<Employee>(builder => builder.HasKey(x => x.Id)); // 配置EmployeeInfo为无键实体 modelBuilder.Entity<EmployeeInfo>().HasNoKey(); }
同时可以删除ConfigureConventions方法里的configurationBuilder.DefaultTypeMapping<EmployeeInfo>();,因为它对复杂类型无效。
2. 验证修改后的完整DbContext代码
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; namespace Test { public class Employee { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } } public class EmployeeInfo { public int EmployeeId { get; set; } public string Name { get; set; } } public class EmployeeDBContext : DbContext { public DbSet<Employee> Employees { get; set; } public EmployeeDBContext() { } public EmployeeDBContext(DbContextOptions<EmployeeDBContext> options) : base(options) { } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer("Data source=localhost;Database=EmployeeDB;User Id=sa;Password=Dev.NET;"); } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<Employee>(builder => builder.HasKey(x => x.Id)); // 配置无键实体 modelBuilder.Entity<EmployeeInfo>().HasNoKey(); } } }
方案生效原因
EF Core要求,当使用SqlQuery<T>查询复杂类型时,T必须是EF Core模型中已注册的实体类型。无键实体就是专门为这种不需要对应数据库表、仅用于承载查询返回结果的DTO设计的,它会告诉EF Core如何将查询结果映射到该类型的属性上。
内容的提问来源于stack exchange,提问作者Thiago Guislotti
相关产品推荐
相关产品推荐

