【问题标题】:Entity Framework Code First: how to map multiple self-referencing many-to-many relationships实体框架代码优先:如何映射多个自引用多对多关系
【发布时间】:2014-11-14 13:07:15
【问题描述】:

我创建了一个实体类型,它具有多个引用相同类型项目的集合属性。换句话说,它反映了一个单独的数据库表,其中的行被任意分组,使得一行可能出现在多个组中。

在下面的简化示例中,Person 类具有 BrothersSisters 集合属性,它们也引用了 Person 实体:

public class Person
{
    public Person()
    {
        Brothers = new Collection<Person>();
        Sisters = new Collection<Person>();
    }

    [Key]
    public string Name { get; set; }

    public int Age { get; set; }

    public virtual ICollection<Person> Brothers { get; set; } 

    public virtual ICollection<Person> Sisters { get; set; } 
}

Entity Framework 似乎认为这是一个有效的模型,但将其解释为创建单个PersonPersons 连接表,无法体现兄弟姐妹关系的分离。

我认为解决方案是使用 fluent API 为两个关系显式映射单独的连接表,但是,尽管进行了大量实验,但我无法让它工作。

有什么建议吗?

谢谢, 蒂姆

【问题讨论】:

  • 你试过了吗,HasMany(p => p.Brothers).WithMany(b => b.Persons).Map(m => m.Table("Person_Brothers");没试过这种类型的关系,但是当 ef 不合作时,我们如何映射多对多。

标签: entity-framework many-to-many code-first self-reference


【解决方案1】:

通过在 DbContext.OnModelCreating 方法中添加这个:

更新根据上面nameEqualsPNamePrubeGoldberg的评论添加了表命名映射:

modelBuilder.Entity<Person>().HasMany(x => x.Brothers).WithMany()
    .Map(x => x.ToTable("Person_Brothers"));
modelBuilder.Entity<Person>().HasMany(x => x.Sisters).WithMany()
    .Map(x => x.ToTable("Person_Sisters"));

我通过了这个单元测试

[TestMethod]
public void TestPersons()
{
    var brother = new Person() { Name = "Brother 1", Age = 10 };
    var sister = new Person() { Name = "Sister 1", Age = 12 };
    var sibling = new Person() { Name = "Sibling 1", Age = 18 };
    sibling.Brothers.Add(brother);
    sibling.Sisters.Add(sister);

    using (var db = new MyDatabase())
    {
        db.Persons.Add(brother);
        db.Persons.Add(sister);
        db.Persons.Add(sibling);

        db.SaveChanges();
    }

    using (var db = new MyDatabase())
    {
        var person = db.Persons
            .Include(x => x.Sisters)
            .Include(x => x.Brothers)
            .FirstOrDefault(x => x.Name.Equals(sibling.Name));

        Assert.IsNotNull(person, "No person");
        Assert.IsTrue(person.Brothers.Count == 1, "No brothers!");
        Assert.IsTrue(person.Sisters.Count == 1, "No sisters");
    }
}

这也会创建您正在谈论的链接表。

【讨论】:

  • 这是一个很好的解决方案。谢谢。
  • 用这段代码,你说brothersibling的兄弟,对吧?但是你必须手动包含关系的另一端(告诉siblingbrother 的兄弟)?
猜你喜欢
  • 2011-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多