实体框架多对多关系到相同的实体类型但具有不同的关系类型

时间:2014-03-28 11:58:53

标签: c# entity-framework model entity relationship

使用Entity Framework 6,我有一个Person类......

public class Person
{
    public int ID { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Relationship> Relationships { get; set; }
}

和关系类

public class Relationship
{
    public int ID { get; set; }
    public RelationshipType DependencyType { get; set; }

    [ForeignKey("Person")]
    public int PersonID { get; set; }
    public virtual Person Person { get; set; }

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

}

我想要表示的是,例如我可能将兄弟姐妹作为关系类型而将UnclesAndAunts作为另一种关系类型并保持这些类型的关系,而无需知道父母是谁,因为他们可能不在数据库中

使用Code First,这会生成一个表格模式......

CREATE TABLE [dbo].[Person](
[ID] [int] IDENTITY(1,1) NOT NULL,
 [Name] [nvarchar](max) NULL,
[Relationship_ID] [int] NULL)

CREATE TABLE [dbo].[Relationship](
    [ID] [int] IDENTITY(1,1) NOT NULL,
[RelationshipType] [int] NOT NULL,
[PersonID] [int] NOT NULL,
[Person_ID] [int] NULL)

PersonID is the main Person of this relationship.
Person_ID is the Person to whom the main person is related to.
I would see the Relationship table containing repeated PersonID data.

这个问题是因为Person表中的Relationship_ID这就是说Person表会有重复的数据,而我希望Relationship表有重复的数据,例如。

Relationship...

ID   RelationshipType PersonID    Person_ID
---------------------------------------------
1    Sibling           1           2
2    Sibling           1           3
3    UnclesAndAunts    1           4

有人可以告诉我应该如何使用模型类来表示这一点,我假设我需要包含一些属性或其他属性。

由于

1 个答案:

答案 0 :(得分:4)

Relationship_ID来自Relationship.RelatedPersons集合。我认为在这里拥有集合是不对的,相反它应该是单个引用 RelatedPerson(单数),因为单个{{1实体描述了完全两个人之间的关系,而不是一个人和一群其他人之间的关系。所以,我建议改变这样的模型:

Relationship

此处public class Person { public int ID { get; set; } public string Name { get; set; } [InverseProperty("Person")] public virtual ICollection<Relationship> Relationships { get; set; } } public class Relationship { public int ID { get; set; } public RelationshipType DependencyType { get; set; } [ForeignKey("Person")] public int PersonID { get; set; } public virtual Person Person { get; set; } [ForeignKey("RelatedPerson")] public int RelatedPersonID { get; set; } public virtual Person RelatedPerson { get; set; } } 属性非常重要,告诉EF [InverseProperty]Relationship.Person的反向导航属性。如果没有该属性,您将在Person.Relationships表中获得三个外键,引用Relationship表。

您可能还需要为其中一个关系禁用级联删除,以避免从PersonPerson禁止多个级联删除路径的例外。可以使用Fluent API完成:

Relationship

一旦你有了这个,你可以添加第二个关系与Fluent API,这将允许你删除模型中的所有属性,因为它们是多余的:

modelBuilder.Entity<Relationship>()
    .HasRequired(r => r.RelatedPerson)
    .WithMany()
    .HasForeignKey(r => r.RelatedPersonID)
    .WillCascadeOnDelete(false);