首页 文章

实体框架代码优先:如何映射多个自引用多对多关系

提问于
浏览
8

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

在以下简化示例中, 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; } 
}

实体框架似乎认为这是一个有效的模型,但解释它是为了创建一个单独的 PersonPersons 连接表,它无法反映兄弟姐妹关系的分离 .

我假设解决方案是使用流畅的API为两个关系显式映射单独的连接表,但是,尽管经过了大量的实验,我仍然无法使其工作 .

有什么建议吗?

蒂姆,谢谢

1 回答

  • 8

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

    UPDATE 根据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");
        }
    }
    

    这也创建了您正在谈论的链接表 .

相关问题