2011-11-06 117 views
1

设置
EF 4.1代码第一次关系表

使用MVC 3 +代码第一次

这里是我的班

public class Member 
    { 
     [Key] 
     public Guid ID { get; set; } 

     [Required] 
     public String Email { get; set; } 

     [Required] 
     public String FirstName { get; set; } 

     [Required] 
     public String LastName { get; set; } 

     public String Sex { get; set; } 

     public String Password { get; set; } 

     public String PasswordSalt { get; set; } 

     public DateTime RegisterDate { get; set; } 

     public DateTime LastOnline { get; set; } 

     public String SecurityQuestion { get; set; } 

     public String SecurityAnswer { get; set; } 

     public virtual ICollection<FamilyMember> Families { get; set; } 

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


    } 


public class Relationship 
    { 
     [Key] 
     public Guid ID { get; set; } 

     [ForeignKey("Member1")] 
     public Guid Member1ID { get; set; } 

     [ForeignKey("Member2")] 
     public Guid Member2ID { get; set; } 

     public Guid RelationshipTypeID { get; set; } 

     public virtual RelationshipType RelationshipType { get; set; } 

     public virtual Member Member1 { get; set; } 

     public virtual Member Member2 { get; set; } 

    } 

这里的问题是

数据库表“Re lationship”正在与下面的列创建:

ID,Member1ID,Member2ID,RelationshipTypeID,Member_ID

为什么创建Member_ID列?

我见过this后,其中用户具有相同类型的设置,但我不确定如何正确定义InverseProperty。我尝试了使用流利的API调用,但从我可以告诉他们不会在这里工作,因为我有两个外键引用同一个表。

任何帮助,将不胜感激!

回答

2

Member_ID是EF为导航属性Member.Relationships创建的外键列。它属于来自Member.Relationships的第三个关联,指的是未在您的Relationship实体中公开的终端。这种关系与Relationship.Member1Relationship.Member2之间的其他两个关系无关,这两个关系在Member中也都没有公开。

我想,这不是你想要的。您需要始终在两个实体中使用端点来创建关联。一个端点始终是导航属性。第二个端点可以也是一个导航属性,但不是必需的,你可以省略第二个导航属性。现在

,什么是不可能的,是导航性能(Member1Member2)于一体的实体与其他实体一个导航性能(Relationships)相关联。这就是你想要做的显然。

我假定你的财产Member.Relationships应该表达的成员或者是Member1Member2的关系,或者说,它在参与关系不管如果为Member1Member2

不幸的是,您无法在模型中正确表达这一点。你必须引入一些像RelationsshipsAsMember1RelationsshipsAsMember2这两个集合,你可以使用另一个问题所示的InverseProperty属性。另外,您可以添加一个连接两个集合的helper属性。但是,这不是一个映射属性,但只读:

public class Member 
{ 
    // ... 

    [InverseProperty("Member1")] 
    public virtual ICollection<Relationship> RelationshipsAsMember1 { get; set; } 
    [InverseProperty("Member2")] 
    public virtual ICollection<Relationship> RelationshipsAsMember2 { get; set; } 

    public IEnumerable<Relationship> AllRelationships 
    { 
     get { return RelationshipsAsMember1.Concat(RelationshipsAsMember2); } 
    } 
} 

访问AllRelationships会导致两个查询和往返到数据库(与延迟加载),它们会在内存连接在一起之前,先加载两个集合。

有了这个映射Member_ID列将消失,你将只能得到两个预期外键列Member1IDMember2ID因为现在你只有两个协会和不是三个了。

你也可以考虑一下Member实体中是否需要Relationships集合。如前所述,双方都不需要导航属性。如果你很少需要从成员到其关系导航,你可以使用查询在Relationship集还取的关系,就像这样:

var relationships = context.Relationships 
    .Where(r => r.Member1ID == givenMemberID || r.Member2ID == givenMemberID) 
    .ToList(); 

......或者......

var relationships = context.Relationships 
     .Where(r => r.Member1ID == givenMemberID) 
    .Concat(context.Relationships 
     .Where(r => r.Member2ID == givenMemberID) 
    .ToList(); 

这将为您提供ID = givenMemberID成员的所有关系,而不需要Member实体上的导航集合。

+0

你让我更多地思考它,而且我认为你甚至不需要Member.Relationships属性是正确的。我想从我过去的作品中,你总是会有一种导航的方式。但是如果我需要加载关系,我可以查询关系表。这样做的一个缺点是在我的View Model中不能轻松获得。 – Jack