2012-11-06 97 views
4

我試了一整天才得到這個工作。我學到了很多關於EF的Fluent API(例如this是一篇很好的文章),但是我沒有成功。實體框架5中的一對一和一對多關係代碼優先

我有三個實體:

public class Address 
{ 
    [Key] 
    public virtual int AddressId { get; set; } 
    public virtual string AddressString { get; set; } 
} 
public class User 
{ 
    [Key] 
    public virtual int UserId { get; set; } 
    public virtual ICollection<Address> Addresses { get; set; } 
} 
public class House 
{ 
    [Key] 
    public virtual int HouseId { get; set; } 
    public virtual Address Address { get; set; } 
} 

,並在

protected override void OnModelCreating(DbModelBuilder modelBuilder) 

試過,我能想到的HasMany, HasOptional, WithOptional, WithOptionalDependentWithOptionalPrincipial所有組合兩個UserHouse我只是無法得到它的工作。我認爲應該清楚,我想要什麼。一個用戶可能有多個地址(首先我想強制至少一個地址,但現在如果用戶可能有地址可選,我會很高興),而一個房子只有一個地址 - 這是需要。如果房子的地址會被級聯刪除,那將會很好。

回答

3

我相信以下幾點應該適合你

public class Address 
{ 
    public int AddressId { get; set; } 
    public string AddressString { get; set; } 
} 

public class User 
{ 
    public int UserId { get; set; } 
    public virtual ICollection<Address> Addresses { get; set; } 
} 

public class House 
{ 
    public int HouseId { get; set; } 
    public virtual Address Address { get; set; } 
} 

public class TestContext : DbContext 
{ 
    public DbSet<Address> Addresses { get; set; } 
    public DbSet<User> Users { get; set; } 
    public DbSet<House> Houses { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<User>().HasMany(u => u.Addresses).WithMany(); 
     modelBuilder.Entity<House>().HasRequired(h => h.Address).WithOptional().Map(m => m.MapKey("AddressId")); 
    } 
} 

請注意,通常情況下最好是自己指定外鍵字段,這可以讓您以後的生活更加輕鬆。如果你這樣做,那麼你可以選擇重寫閣爲以下幾點:

public class House 
{ 
    public int HouseId { get; set; } 
    public int AddressId { get; set; } 
    public virtual Address Address { get; set; } 
} 

公約將連接AddressId和地址。如果你有房子和地址之間有一個一對一映射,你也可以將它們鏈接在他們的主鍵:

public class House 
{ 
    [ForeignKey("Address")]    
    public int HouseId { get; set; } 
    public virtual Address Address { get; set; } 
} 

你提到你想執行至少一個地址 - 這是不可能的與一對多的關係。如果用戶只有一個地址,則只能這樣做,此時可以在User類上添加必需的AddressId屬性。

一個其他的評論 - 你在你的代碼中做了一切虛擬。您只需要使導航屬性變爲虛擬。

+0

好吧,今天有更多的睡眠,我想我的問題是在初始化,而不是在上下文......但是,您的答案對我有價值,也希望對其他人有用。 –

1

什麼是這樣的:

強制執行AddressHouse

modelBuilder.Entity<House>().HasRequired(d => d.Address); 

要創建UserAddress之間的一個一對多的關係:

modelBuilder.Entity<User>().HasMany(u => u.Addresses).WithMany().Map(x => 
{ 
    x.MapLeftKey("UserId"); 
    x.MapRightKey("AddressId"); 
    x.ToTable("UserAddress"); 
}); 

什麼這應該做的是創建一個名爲UserAddress的表,該表將UserAddress

或者,你可以爲UserAddress創建POCO自己和修改有關的表格:

public class UserAddress 
{ 
    [Key] 
    public int UserAddressId { get; set; } 
    public User User { get; set; } 
    public Address Address { get; set; } 
} 

public User 
{ 
    ... 
    public virtual ICollection<UserAddress> UserAddresses { get; set; } 
    ... 
} 

public Address 
{ 
    ... 
    public virtual ICollection<UserAddress> UserAddresses { get; set; } 
    ... 
} 

然後您將必須滿足下列條件,以確保兩個UserAddress是必需的:

modelBuilder.Entity<UserAddress>().HasRequired(u => u.Address); 
modelBuilder.Entity<UserAddress>().HasRequired(u => u.User); 
相關問題