2011-02-07 188 views
2

我和我的朋友在工作中使用Code First Fluent API定義實體框架4 CTP 5中的映射時遇到了一些困難,我希望有人能夠指出我們正在製作的一些明顯的愚蠢錯誤。下面是有關數據庫設置:實體框架4映射問題

Person 
------------ 
int PersonId (pk) 
varchar Name 

Contact 
-------------- 
int ContactId (pk) 
int ContactTypeId 
varchar Text 

所以,一個人可以有零個或多個電話號碼和零個或多個電子郵件地址。電話和電子郵件地址存儲在「聯繫人」表中,該表是一種簡單的按層次結構繼承映射(使用ContactTypeId作爲類型鑑別器)。在代碼中,我們有:

public class Person { 
    public int PersonId { get; set; } 
    public string Name { get; set; } 
    public ICollection<Phone> Phones { get; set; } 
    public ICollection<Email> Emails { get; set; } 
} 

public abstract class Contact { 
    public int ContactId { get; set; } 
    public string Text { get; set; } 
    public Person Person 
} 

public class Phone : Contact {}  
public class Email : Contact {} 

...以及數據庫映射,我們有:

public class ContactMapping : IFluentEntityFrameworkMapping 
{ 
    public void OnModelCreating(ModelBuilder modelBuilder) 
    { 
     EntityTypeConfiguration<Contact> configuration = modelBuilder.Entity<Contact>(); 

     config.HasKey(c => c.ContactId) 
      .Map<Email>(e => e.Requires("ContactTypeId").HasValue(1)) 
      .Map<Phone>(p => p.Requires("ContactTypeId").HasValue(2)); 
    } 
} 

public class PersonMapping : IFluentEntityFrameworkMapping 
{ 
    public void OnModelCreating(ModelBuilder modelBuilder) 
    { 
     EntityTypeConfiguration<Person> config = modelBuilder.Entity<Person>(); 

     config.HasMany(p => p.Phones).WithRequired(p => p.Person).HasForeignKey(p => p.PersonId); 
     config.HasMany(p => p.Emails).WithRequired(e => e.Person).HasForeignKey(e => e.PersonId); 
    } 
} 

當我們試圖對這個東西運行簡單的單元測試,如果我們只是一味的拉電話號碼或電子郵件地址的後面集合,一切都很好。但是,如果我們試圖拉取人員集合,我們會得到映射錯誤。上述任何代碼有沒有明顯的錯誤?

預先感謝任何幫助, KurtC

回答

3

唯一的例外來自於事實,你要創建2個協會與Contact類一個端點。換句話說,Contact.PersonPerson.PhonesPerson.Emails的逆特性,這是不可能的,至少在EF CTP5中是這樣。以下是解決此問題的一種方法:

public class Person 
{ 
    public int PersonId { get; set; } 
    public string Name { get; set; }     
    public ICollection<Contact> Contacts { get; set; } 
} 

public abstract class Contact 
{ 
    public int ContactId { get; set; } 
    public string Text { get; set; } 
    public int PersonId { get; set; }   
    public Person Person { get; set; } 
} 

public class Phone : Contact { } 
public class Email : Contact { } 

public class Context : DbContext 
{ 
    public DbSet<Contact> Contacts { get; set; } 
    public DbSet<Person> Persons { get; set; } 
    protected override void OnModelCreating(ModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Contact>() 
        .Map<Email>(e => e.Requires("ContactTypeId").HasValue(1)) 
        .Map<Phone>(p => p.Requires("ContactTypeId").HasValue(2)); 

     modelBuilder.Entity<Person>() 
        .HasMany(p => p.Contacts) 
        .WithRequired(e => e.Person) 
        .HasForeignKey(e => e.PersonId); 
    } 
}