【问题标题】:EF one to many with linking tableEF 一对多与链接表
【发布时间】:2013-10-02 02:30:22
【问题描述】:

我是 Entity Framework 的新手,我正在努力处理从我的 POCO 类创建的数据库。我有一个看起来像这样的通用类:

public class Comment
{
   public int Id { get; set; }
   public string Text { get; set; }
   public DateTime CreatedDate { get; set; }
}

并且 cmets 可以添加到许多对象中,例如 Person 和 Vehicle,所以我将拥有这些类

public class Person
{
   public int Id { get; set; }
   public List<Comment> Comments { get; set; }
}

public class Vehicle
{
   public int Id { get; set; }
   public List<Comment> Comments { get; set; }
}

当 EF 生成我的数据库时,它会添加一个 Person_Id 和 Vehicle_Id,这对我来说是不正确的,因为: a)它表明评论与人和车辆有关,它实际上应该是“独立”对象 b) 可以将注释添加到需要更改表的未来对象。

我怎样才能让 EF 宁愿为此使用链接表?

(注意:我不能也不想向 Comment 类添加导航属性,因为每次新对象需要 cmets 时都需要更改类,并且我的评论类在我的通用库中,与人或车辆无关)

我找到了这篇文章,但我很难从中得到答案:http://weblogs.asp.net/manavi/archive/2011/05/17/associations-in-ef-4-1-code-first-part-6-many-valued-associations.aspx

【问题讨论】:

    标签: entity-framework one-to-many relationship


    【解决方案1】:

    EF 正在Comment 表上生成Person_IdVehicle_Id 列,它们可以为空。这意味着评论可以链接到一个人或一辆车或一个人和一辆车或两者都没有。所以它真的是一个“独立”的对象。

    您可能正在寻找的模型使用inheritance

    public class Comment
    {
        public int Id { get; set; }
        public string Text { get; set; }
        public DateTime CreatedDate { get; set; }
    }
    
    public class VehicleComment : Comment
    {
        public int VehicleID;
    }
    
    public class PersonComment : Comment
    {
        public int PersonID;
    }
    
    
    public class Person
    {
        public int Id { get; set; }
        public List<PersonComment> Comments { get; set; }
    }
    
    public class Vehicle
    {
        public int Id { get; set; }
        public List<VehicleComment> Comments { get; set; }
    }
    

    EF 将默认为每个层次结构的表继承。这将创建一个类似于您已经拥有的表,但具有“鉴别器”列。然后,您可以直接使用 DbSet&lt;VehicleComment&gt;,而不必查询 DbSet&lt;Comment&gt;...Where(x =&gt; x.Vehicle_Id != null) 来获取有关车辆的 cmets。

    是的,添加到未来对象的 cmets 将需要更改表,但在使用 Code First 时这并不是什么困难。而且编写代码变得更加简单,因为您不需要通过某种链接实体。

    编辑 当您添加一个与 Comments 有关系的新实体时发生的变化是另一个外键列被添加到 Comments 表中以对该关系建模。向现有表添加可为空的列可能是您可以获得的最简单的架构更改。至于更改控制,无论如何您都在为新实体添加一个表 - 所以您有一个包含几行额外代码的迁移文件。

    另外,拥有一个链接表意味着放弃外键约束、级联删除等,不是吗?

    public class FooComment : Comment
    {
       //FooID means one more column in the table
       public int FooID;
    }
    
    public class Foo
    {
        public int Id { get; set; }
        public List<FooComment> Comments { get; set; }
    }
    

    【讨论】:

    • 感谢您的建议,我对将来更改表格的担忧不是与难度有关,而是与更改控制有关,这实际上是对我的要求的过度简化,在我的应用程序中这可能会很大实施挑战。另外,从模式的角度来看,我认为必须为每个可能引用它的实体更新一个通用实体是错误的,人们可能会以两种方式争论,但我不喜欢它。我会测试你的建议,但如果它会创建一个 PersonComment 表和一个 VehicleComment 表,它可能对我不起作用
    • @AdriaanDavel Table Per Hierarchy 为所有 cmets 创建一个表 - 类似于您已经拥有的表,但具有“鉴别器”列。请参阅我的编辑,了解使用 TPH 时实际发生的变化。
    猜你喜欢
    • 1970-01-01
    • 2018-09-01
    • 2012-05-25
    • 1970-01-01
    • 2021-01-14
    • 1970-01-01
    • 2019-11-27
    • 1970-01-01
    • 2023-01-13
    相关资源
    最近更新 更多