2013-04-08 36 views
1

我已經通過StackOverflow上的幾個線程讀過,但一直沒能弄清楚。我希望有人能提供一些建議。我有一些看起來像這樣的POCO類:自我相關的外部參照表的代碼第一映射

Person 
{ 
    int PersonCode {get; set;} 
    ... 
    virtual List<PersonContact> {get; set;} 
} 

PersonContact 
{ 
    int PersonPersonCode {get; set;} 
    int ContactPersonCode {get; set;} 
    int PersonContactTypeCode {get; set;} 

    virtual PersonContactType {get; set;} 
    virtual Person Person {get; set;} // not sure I really need this one 
    virtual Person Contact {get; set;} 
} 

每個人記錄將有零到許多PersonContact記錄。每個PersonContact記錄都將一個Person記錄鏈接到另一個Person記錄,並使用PersonContactTypeCode指示兩個Person記錄之間的關係類型。

我需要能夠映射這個,以便一個人記錄可以導航到他的相關PersonContact記錄。事情是這樣的:

var john = new Person(...); 
var david = new Person(...); 
john.PersonContacts.Add(new PersonContact 
    { 
    Contact = david, 
    PersonContactType = ... // manager 
    }); 

然後

john.PersonContacts 
    .Where(c => c.PersonContactType.PersonContactTypeCode == "manager") 
    .FirstOrDefault(); 

將返回

david 

我都試過,我也很難記得在那裏我開始數據註釋的這麼多的組合和流利的API。我似乎有這種組合的好運:

modelBuilder.Entity<Person>() 
    .HasMany(entity => entity.PersonContacts) 
     .WithRequired(person => person.Person) 
     .HasForeignKey(xref => xref.PersonPersonCode) 
     .WillCascadeOnDelete(false); 

modelBuilder.Entity<Person>() 
    .HasMany(entity => entity.PersonContacts) 
     .WithRequired(xref => xref.Contact) 
     .HasForeignKey(entity => entity.ContactPersonCode) 
     .WillCascadeOnDelete(false); 

但是,當我嘗試不止一個PersonContact添加到一個人,我得到這個錯誤:

Multiplicity constraint violated. The role 'Person_PersonContacts_Source' of the 
relationship '...Entities.Person_PersonContacts' has multiplicity 
1 or 0..1. 

我真的很感謝所有幫助,我現在完全陷入困境。順便說一下,如有必要,我願意改變這些POCO。

回答

1

我想這是因爲您使用的是相同的導航屬性鏈接到PersonContact.PersonPersonContact.Contact

假設這樣的:

Person 
{ 
    int PersonCode {get; set;} 
    ... 
    virtual ICollection<PersonContact> PersonContacts {get; set;} 
} 

試着這麼做:

modelBuilder.Entity<PersonContact>() 
    .HasRequired(x => x.Person) 
     .WithMany(x => x.PersonContacts) 
     .HasForeignKey(x => x.PersonPersonCode) 
     .WillCascadeOnDelete(false); 

modelBuilder.Entity<PersonContact>() 
    .HasRequired(x => x.Contact) 
     .WithMany() 
     .HasForeignKey(x => x.ContactPersonCode) 
     .WillCascadeOnDelete(false); 
+0

明天當我回到辦公室時,我會試試這個,我會讓你知道它是如何運行的。 – 2013-04-09 02:01:44

+0

我對這個解決方案做了一些小改動。它的工作,謝謝你! – 2013-04-10 13:28:03

+0

微小的變化是什麼? – 2013-08-05 11:27:55

1

試試這個:

public class Person 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int PersonId {get; set;} 
    ... 
    public virtual ICollection<PersonContact> PersonContacts {get; set;} 
} 


public class PersonContact 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int ContactId {get; set;} 

    [ForeignKey("Person"), DatabaseGenerated(DatabaseGeneratedOption.None)] 
    public int PersonId {get; set;}  

    public virtual Person Person {get; set;}   
} 

我用Property Mapping,而不是像Fluent Mapping在你嘗試嘗試。 如果您有任何問題,請告訴我。就你們兩個實體之間的關係而言,這就是你所需要的。

+0

你如何處理級聯刪除? – 2013-04-08 23:45:16

+0

@kirsteng'實體框架'確保'對象'是通過'cascade delete'創建的。關於此事的鏈接http://stackoverflow.com/questions/5520418/entity-framework-code-first-delete-with-cascade – Komengem 2013-04-09 00:08:34

+0

糟糕,我的意思是你怎麼把級聯刪除掉? – 2013-04-09 00:25:28

0

我設法得到類似的方法是使用下面

工作的東西在我的領域類

public class PersonContact 
{ 
    public int Id { get; set; } 

    [Required] 
    public virtual Person ContactPerson { get; set; } 

    [Required] 
    public virtual Person Person { get; set; } 

[Required] 
public int ContactType { get; set; } 

} 

public class Person 
{ 
int Id { get; set; } 

    private readonly List<PersonContact> _contacts = new List<Contact>(); 

    public virtual List<PersonContact> Contacts 
    { 
     get 
     { 
      return this._contacts; 
     } 
    } 
} 

在我的上下文

public DbSet<Person> People { get; set; } 
public DbSet<PersonContact> Contacts { get; set; } 

我犯了一個移民這一變化,並有編輯生成的創建表代碼以設置 級聯刪除爲fwo到Person表中的外鍵,在PersonContac內部t表。

我在PersonContact表中獲得了一個額外的Person_Id1列。它似乎用與Person_Id相同的數據填充。當我創建一個綁定源時,這似乎是EF所需要的 - 因爲沒有它就會得到錯誤。

我不會放置明確的外鍵,讓遷移創建它們。

+1

I自從你要求改進之後,你的答案做了一些修改。您在PersonContact表中獲得'額外的Person_Id1列'的原因是您沒有在您的POCO類中映射'PersonId'外鍵。另外下面的方法可以解決這個問題 – Komengem 2013-04-08 23:02:14

+0

謝謝,我通常似乎能夠逃脫,而沒有在POCO類中明確定義FK。我應該總是明確地定義它們還是隻在這樣的場景中定義? – 2013-04-08 23:25:17

+0

您可以執行屬性映射或流利映射。在這個問題中,他嘗試了流暢的映射,在我的答案中屬於我做了屬性映射,我喜歡,在我的情況下更容易遵循。注意:您的答案中的編輯未獲批准,但您可以與我的答案相關 – Komengem 2013-04-08 23:39:24

相關問題