Entity Framework Many to Many relationship to same entity type but with different relationship type

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-12 20:35:59

问题


Working with Entity Framework 6, I have a Person class...

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

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

and a Relationship Class

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

}

What I want this to represent is that for example I might have Siblings as a relationship type and UnclesAndAunts as another relationship type and hold these types of relationships without the need to know who the parents are as they may not be in the database.

With Code First, this produces a table schema of...

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

and

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.

The problem with this is that because of the Relationship_ID in the Person table this is saying that the Person table will have repeated data whereas I want the Relationship table to have the repeated data e.g.

Relationship...

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

Can someone tell me how I should represent this with the Model Classes, I assume there are some attributes or other that I need to include.

Thanks


回答1:


The Relationship_ID stems from the Relationship.RelatedPersons collection. I think it's not correct to have a collection here, instead it should be a single reference RelatedPerson (singular) since a single Relationship entity describes the relationship between exactly two people, not between a person and a collection of other people. So, I'd propose to change the model like this:

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

The [InverseProperty] attribute is important here to tell EF that Relationship.Person is the inverse navigation property of Person.Relationships. Without that attribute you would get three foreign keys in the Relationship table refering to the Person table.

You probably also need to disable cascading delete for one of the relationships to avoid an exception about forbidden multiple cascading delete paths from Person to Relationship. It can be done with Fluent API:

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

Once you have that you can add the second relationship with Fluent API as well which would allow you to remove all attributes from the model as they are redundant then:

modelBuilder.Entity<Relationship>()
    .HasRequired(r => r.Person)
    .WithMany(p => p.Relationships)
    .HasForeignKey(r => r.PersonID);


来源:https://stackoverflow.com/questions/22712199/entity-framework-many-to-many-relationship-to-same-entity-type-but-with-differen

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!