2014-05-07 193 views
1

時立即將性能我有一些代碼,看起來有點像這樣:實體框架應插入

var query = from row in context.Orders.Include("Customer") 
where row.Id = 5 
select row; 

var result = query.FirstOrDefault(); 

if(result == null) 
{ 
    result = new Order {CustomerId=5,...} 
    context.Orders.Add(result); 
    context.SaveChanges(); 

    // at this point result.Customer is null 
    // and is not lazy-loaded by EF on access 
} 

return result; 

正如你可以看到上面的代碼,然後如果插入發生,那麼結果的顧客財產不包括在內,稍後在我的代碼中給我一個錯誤。

當插入result時,如何確保從數據庫加載result.Customer?我可以這樣做而不用手動選擇它嗎?

+2

「正如你可以看到上面的代碼...結果的客戶屬性不包括」我們怎麼看?代碼的確切問題是什麼?你在代碼中看到什麼錯誤消息?目前很難理解你所要求的。 – BlueM

+0

@Iain Galloway感謝您的編輯。 – BlueM

+0

您的查詢看起來很奇怪,因爲您正在檢索ID爲5的'Order',如果您沒有找到它,那麼您將爲ID = 5的'Customer'創建一個新訂單。您確定查詢不應該是'客戶包括(「訂單」)cust.ID = 5選擇客戶? – Colin

回答

3

如果不選擇Customer對象,EF無法提供神奇功能。你在這裏只有一個ID。 Something將需要去數據庫並找到ID#5的客戶對象。

EF無法延遲加載它,因爲您的result實際上是POCO Order而不是EF知道如何延遲加載的代理。

做可能是通過ID查詢了客戶和價值,而不是設置的關係(或者和)的最簡單的事情: -

if(result == null) 
{ 
    result = new Order 
    { 
    Customer = context.Customers.Single(x => x.Id == 5); 
    ... 
    }; 
    context.Orders.Add(result); 
    context.SaveChanges(); 
} 

或者您可以使用context.Orders.Create()這樣你與擺在首位的EF代理工作: -

if(result == null) 
{ 
    var result = context.Orders.Create(); 
    result.CustomerId = 5; 
    ... 
} 

要小心,雖然,這取決於預期的域名的行爲也往往不是一個好主意混合查詢,像這樣的命令了。您可能想要圍繞CQRS進行一些閱讀 - 例如http://cqrs.nu/

創建訂單是一個相當重要的操作。將它填充到一個不存在的訂單的查詢中可能在未來回來並咬你。

+0

我的例子是當然簡化,只要求基礎知識,因此這個答案非常適合我的代碼。我會盡力實現它,然後我的「客戶」查詢將完成我需要的所有內容。真正的代碼可能包含10個客戶,而我的真實場景與訂單等無關,只是因爲大部分都可以輕鬆地與此相關。 –