【问题标题】:EF inheritance with TPT - how to specify the foreign key column name?EF 继承与 TPT - 如何指定外键列名?
【发布时间】:2015-06-23 21:28:53
【问题描述】:

我想将两个派生类映射到两个表(TPT)

[Table("User")]
public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
}

[Table("Employee")]
public class Employee : User
{
    public int UserId { get; set; }
    public string DeptName { get; set; }
}

表已经存在(即我无法修改架构)并且定义如下:

请注意,表Employee 中的列UserId 既是它的PK 也是表User 的列Id 的FK。

DbContext 尽可能直接 - 没有定义流畅的映射。

public class TestInheritContext : DbContext
{
    public DbSet<User> Users { get; set; }
}

当尝试访问 Users 集合时,我收到以下 EF 异常:

System.Data.SqlClient.SqlException:列名“Id”无效。

显然,它试图从表 Employee 中读取列 Id

我见过的所有 TPT 示例在所有表中都使用相同的 PK 列名。例如,this one

我该如何解决?

【问题讨论】:

  • 您是否尝试在您的UserId 属性上添加[Key("UserId")]
  • @jbl 该属性已映射到同名列。问题是,基类的Id 属性在类Employee 中继承,EF 尝试从表Employee 中的列Id 中读取它,但该列不存在。
  • 所以我猜你没有尝试 ;-) 我流畅地映射 TPT 层次结构,为父键列和子键列使用不同的列名。唯一需要的一点是在这两种类型中指定 Key 及其列名。
  • 确实试过了。同样的错误。顺便说一句,[Key] 属性 ctor 不带任何参数。我同时使用了[Key][Column("UserId")]
  • @jbl 我已经检查过了。我很好奇.OfType() 是在数据库上还是在本地运行。很高兴地报告DbSet&lt;Employee&gt;DbSet&lt;User&gt;.OfType&lt;Employee&gt; 都可以工作并且生成的SQL 是相同的。相当整洁。

标签: entity-framework single-table-inheritance


【解决方案1】:

想通了。

首先,为了对此进行调试,查看 EF 在幕后创建的实际映射很有帮助。

我安装了EF Power Tools VS 扩展,右击上下文文件,

Entity Framework -&gt; View Entity Data Model

得到了这个:

注意实体Employee 有它自己的UserId 属性继承的Id 属性。

所以我做的第一件事就是从派生类中删除UserId 属性:

[Table("Employee")]
public class Employee : User
{
    // not needed
    //public int UserId { get; set; } 

    public string DeptName { get; set; }
}

但这还不够。我现在有来自基类的Id 属性,它必须指向两个不同命名的列,具体取决于它来自哪个表/实体:

对于User:Id => Id
对于Employee:Id => UserId

我无法为此使用属性,所以我将使用流畅的语法。

对于User 实体,我没有 做任何事情,因为列名与属性名匹配。

对于Employee 实体,我必须进行干预:

public class TestInheritContext : DbContext
{
    public DbSet<User> Users { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Employee>()
            .Property(e => e.Id)
            .HasColumnName("UserId");
    }
}

这最终产生了正确的映射:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-08
    • 2014-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多