2012-10-21 96 views
4

使用實體框架5EF多重關係

所以我有一個客戶。客戶可以有許多地址,但至少有一個。其中一個地址也將被設置爲主地址(必需)。我嘗試了各種映射,但到目前爲止,我在構建或種子數據庫時遇到錯誤。

客戶:

public class Customer 
{ 
    public int CustomerId { get; set;} 
    public String CustomerName { get; set; } 
    public int PrimaryAddressId { get; set; } 
    public virtual CustomerAddress PrimaryAddress { get; set; } 
    public virtual ICollection<CustomerAddress> CustomerAddresses { get; set; }  
} 

地址:

public class CustomerAddress : Address 
{ 
    public int CustomerAddressId { get; set; } 
    public int CustomerId { get; set; } 
    public virtual Customer Customer { get; set; } 
} 

我映射的這一部分是否正常工作。它位於CustomerAddress上。

 this.HasRequired(c => c.Customer) 
      .WithMany(d => d.CustomerAddresses) 
      .HasForeignKey(c => c.CustomerId); 

但是,如何指定在Customer中設置PrimaryAddress的正確映射?還是這是錯誤的方法?

感謝

編輯 - 同時使用阿諾德和LueTM的答案:

此代碼現在工作。

客戶:

public class Customer 
{ 
    public int CustomerId { get; set;} 
    public String CustomerName { get; set; } 
    // public int PrimaryAddressId { get; set; } created in mapping 
    public virtual CustomerAddress PrimaryAddress { get; set; } 
    public virtual ICollection<CustomerAddress> CustomerAddresses { get; set; }  
} 

地址:

public class CustomerAddress : Address 
{ 
    public int CustomerAddressId { get; set; } 
    public int CustomerId { get; set; } 
    public virtual Customer Customer { get; set; } 
} 

客戶映射:

 modelBuilder.Entity<Customer> 
      .HasOptional(c => c.PrimaryAddress) 
      .WithOptionalDependent().Map(m => m.MapKey("PrimaryAddressId")); 

     modelBuilder.Entity<Customer> 
      .HasMany(c => c.CustomerAddresses) 
      .WithRequired(c => c.Customer) 
      .HasForeignKey(c => c.CustomerId) 
      .WillCascadeOnDelete(false); 

我使用存儲庫,以確保新的地址首先創建,保存,然後也設置爲主要並再次保存。存儲庫確保主要是「必需的」。

+2

請在出現的地方顯示錯誤和代碼。 (通過編輯你的文章) –

回答

1

既然你沒有顯示異常,我不得不假設你遇到了雞蛋問題。

如果您將PrimaryAddress設置爲所需屬性,則EF必須具有用於建立外鍵的現有地址Id(在中設置PrimaryAddressId)。但是,由於Address需要Customer,因此您無法在其客戶之前存儲地址。如果您嘗試在一次存取中保存地址和客戶,則EF無法確定插入的正確順序,因爲它需要將兩個對象與另一個對象的生成Id一起插入。

因此,AddressCustomer必須有一個可選的外鍵。

我會讓Customer.PrimaryAddressId可選:

modelBuilder.Entity<Customer>().HasOptional(c => c.PrimaryAddress) 
    .WithOptionalDependent(); 

您現在可以存儲地址,並分配一個主地址在separeate交易客戶。但是您需要業務邏輯來確保Customer始終具有主要地址。

如果你想保存通知客戶和地址在一個事務,一個方法可以是一個IsPrimary屬性(布爾)添加到CustomerAddress並確保始終只有一個地址有true

+0

是的這個工程。您是對的,試圖保存這兩個地址並將其作爲主要交易。猜測我關注的主要地址是「required」。爲了解決這個問題:它現在生成它自己的forgeign密鑰。我可以將其映射到我自己的「PrimaryAddressId」嗎? – Sander

+1

也解決了。我刪除了PrimaryAddress id,而是爲它添加了映射: this.HasOptional(c => c.PrimaryAddress) .WithOptionalDependent()。Map(m => m.MapKey(「PrimaryAddressId」)); – Sander

+0

啊,沒有看到你的評論,但很高興你找到了它! –