1

我有一個Customers表和一個Addresses表。客戶可以擁有很多地址,但也有一個標記爲主要地址的地址(如果他們有地址)。實體框架代碼第一次自定義加入

代碼中有某種方式,我可以在客戶POCO中放一個名爲「PrimaryAddress」的字段,並使用類似Customers.Include(customer => customer.PrimaryAddress)的地址來獲取地址與客戶有關並且主要位已設置?

我認爲下一個最好的事情就是在SQL中編寫一個定製連接的視圖?

謝謝。

回答

3

我不認爲這是直接可能的。如果你映射了一些東西,它會以關係或列結束。因此,如果你希望看看你的客戶,如:

它最終將作爲表:

CREATE TABLE dbo.Customers 
(
    ... 
    PrimaryAddress_ID INT NULL 
) 

取決於你要麼已經Addresses映射爲1 Address實體定義:N(Customer_IDAddresse s表或M:N(聯結表)關係

這不是很好,因爲還應該有一些約束,PrimaryAddress_ID必須來自與客戶相關的地址託梅爾。這種限制可能需要通過觸發器進行檢查。

除非您正在構建只讀應用程序,或者您已準備好定義INSTEAD OF觸發器,否則視圖也不行。

你可以不用映射:

public class Customer 
{ 
    ... 
    public ICollection<Address> Addresses { get; set; } 

    [NotMapped] 
    public Address PrimaryAddress 
    { 
     get 
     { 
      return Addresses.Single(a => a.IsPrimary); 
     } 
     // If you need set you can implement it in similar way 
    } 
} 

您還可以定義它沒有屬性,但你需要使用IgnoreOnModelCreating

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<Customer>() 
     .Ignore(c => c.PrimaryAddress); 
} 

這種方法的缺點是,它將始終加載所有地址。

如果你知道你將不再需要其他的則主要地址,您可以使用:

context.Entry<Customer(customer) 
    .Collection(c => c.Addresses) 
    .Query() 
    .Where(a => a.IsPrimary) 
    .Load(); 

這將加載只有小學地址,但你必須首先加載客戶,所以你將不得不roundrips數據庫。

+0

謝謝,那裏有一些有趣的東西。我應該提到該表已經在數據庫中,所以我不擔心代碼生成方面的事情,但是我從你的文章中學到了一些新的東西!儘管我只是用於搜索結果,但我仍然可以使用視圖,但我不確定我喜歡多次往返的想法。 – stewartml 2011-03-20 12:07:41