EF一对多与链接表

时间:2013-10-02 02:30:22

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

我是Entity Framework的新手,我正在努力处理从我的POCO类创建的数据库。我有一个通用类,如下所示:

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

评论可以添加到很多对象中,例如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类中添加导航属性,因为每次新对象需要注释时都需要更改类,而我的注释类在我的通用库中,与人或车无关)

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

1 个答案:

答案 0 :(得分:0)

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

您可能正在寻找的模型使用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将默认为每层次表继承。这将创建一个类似于您已有的表,但带有“Discriminator”列。然后,您可以直接使用DbSet<VehicleComment>,而不必查询DbSet<Comment> ... Where(x => x.Vehicle_Id != null)以获取有关车辆的评论。

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

修改 添加与“注释”关系的新实体时发生的更改是将另一个外键列添加到“注释”表以对该关系建模。将可空列添加到现有表可能就像您可以获得的架构更改一样简单。至于更改控制,无论如何都要为新实体添加一个表 - 所以你有一个包含一些额外代码行的迁移文件。

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

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; }
}