2014-03-28 50 views
1

与实体框架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作为另一种关系类型,并保存这些类型的关系,而无需知道父母是谁,因为他们可能不在数据库中。

随着代码首先,这将产生的表模式...

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. 

的问题,这是因为Relationship_ID的Person表中,这是说, Person表将具有重复的数据,而我希望关系表具有重复的数据,例如

Relationship... 

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

有人能告诉我应该如何用Model Classes来表示这个,我假设有一些属性或其他需要包含的属性。

感谢

回答

2

Relationship_IDRelationship.RelatedPersons收集茎。我认为这是不正确的有收集这里,相反,它应该是因为一个Relationship实体单参考RelatedPerson(单数)精确地描述了人与人之间的关系,而不是一个人,其他的集合之间人。所以,我建议改变模型是这样的:

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

[InverseProperty]属性是非常重要的在这里告诉EF这Relationship.PersonPerson.Relationships逆导航属性。如果没有该属性,您将在Relationship表中获得三个外键,该表指向Person表。

您可能还需要禁用其中一个关系的级联删除,以避免有关禁止从PersonRelationship的多个级联删除路径的例外情况。它可以用流利的API来完成:

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

一旦你有,你可以加用流利的API第二关系,以及这将允许您从模型中移除所有属性,因为它们是那么多余的:

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

绝对没错,我只是把关系弄错了,最后得到了一个解决方案,与你所建议的一致。唯一的区别是,为了完整性,我添加了第二个ICollection虚拟属性,其InverseProperty为“RelatedPerson”。另外,我没有去Fluent API路由,我只是将RelatedId和RelatedPersonId设置为空(int?),从而解决了级联问题。谢谢。 – Hoots

相关问题