2011-11-06 120 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