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

EF Core 5中如何为两个结构相同的SQL表共用同一个模型类

问题原因

EF Core 默认会将CLR实体类的类名作为映射的数据库表名,你用同一个TableRecord类绑定两个DbSet时,EF Core 无法自动识别两个不同的表映射关系,最终生成的SQL会指向不存在的TableRecord表,因此抛出Invalid object name 'TableRecord'错误。

解决方案

有两种常用方案可以实现同结构表共用同一个实体类,无需重复写属性代码:

方案1:继承空子类实现(最简单,推荐)

你只需要定义两个继承自TableRecord的空类即可,不需要重复编写属性代码,EF Core 会自动按照子类名/DbSet属性名匹配对应的表:

// 原有实体类不变
public class TableRecord
{
    public int Id { get; set; }
    public DateTime Date { get; set; }
    public string Title { get; set; }
}

// 新增两个空的子类
public class Table1 : TableRecord {}
public class Table2 : TableRecord {}

// 修改DbContext中的DbSet定义
public class MyContext : DbContext
{
    // 其他原有代码不变
    public virtual DbSet<Table1> Table1 { get; set; }
    public virtual DbSet<Table2> Table2 { get; set; }
}

注意:EF Core默认会对继承类启用TPH继承策略,自动加Discriminator查询条件,你可以在OnModelCreating中添加以下配置关闭该行为,完全匹配现有表结构:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Table1>().HasBaseType((Type)null);
    modelBuilder.Entity<Table2>().HasBaseType((Type)null);
}

修改后原有查询代码不需要改动,直接使用context.Table1、context.Table2即可正常操作。

方案2:共享类型实体配置(无需新增类)

如果你不想新增任何类,可以在OnModelCreating中配置共享类型实体,为同一个TableRecord类绑定两个不同的表映射:

第一步:重写OnModelCreating方法

public class MyContext : DbContext
{
    // 其他原有代码不变
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // 配置Table1的映射
        modelBuilder.SharedTypeEntity<TableRecord>("Table1", tb =>
        {
            tb.ToTable("Table1");
            tb.HasKey(x => x.Id);
            tb.Property(x => x.Title).HasMaxLength(100);
            // 其余字段配置按需添加即可
        });

        // 配置Table2的映射
        modelBuilder.SharedTypeEntity<TableRecord>("Table2", tb =>
        {
            tb.ToTable("Table2");
            tb.HasKey(x => x.Id);
            tb.Property(x => x.Title).HasMaxLength(100);
        });
    }
}

第二步:调整查询写法

查询时需要通过Set<T>(string name)方法指定要操作的实体名:

// 查询Table1的数据
var results = context.Set<TableRecord>("Table1").Where(x => x.Title.Contains("asd")).ToList();
// 查询Table2的数据
var results2 = context.Set<TableRecord>("Table2").Where(x => x.Title.Contains("asd")).ToList();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 10:48:05