2012-03-28 31 views
0

最近,我們關閉了實體框架的延遲加載和代理生成。在此之前,在我們對EF進行了新的更改之後,我們會收到整個對象圖。我現在正在做的是,在提交之後,我調用存儲庫上的FindById方法來獲取新對象(我將導航屬性包含在newley創建的對象中)。我的問題是,這是創建後的標準做法,還是客戶端應該負責第二次調用服務以獲取新創建的對象?在使用Service和Entity Framework 4.1時保存並返回新創建的對象?

public SomeObject Create(SomeObject someObject) 
{ 
    _repository.Add(someObject); 
    _repository.UnitOfwork.Commit() 

    //this did not exist when lazy loading and proxy generation were enabled. 
    var newObject = _repository.FindById(someObject.Id); 
    return newObject; 

    //Before we would jsut return the created object because everything was loaded. 
    //return someObject 

} 

我只是想知道這是否是一個最佳實踐的對象與延遲加載和代理的創建禁用創建後:在服務

保存方法。我很想知道其他開發人員如何處理這個問題。

+0

我不明白你爲什麼要加載你剛剛保存,而且還有在手的對象。如果'FindById'使用'Commit'使用的同一個上下文,'newObject'只會引用與'someObject'相同的對象,它仍然與上下文相連。我的猜測是你的問題與加載導航屬性有關,但對我而言並不明確。 FindById是否包含所有導航屬性的Include屬性,這些導航屬性應該取代以前的惰性加載? – Slauma 2012-03-28 13:13:11

+0

@Slauma,你對包含和導航屬性是正確的。我確實想在提交後加載導航屬性。 – DDiVita 2012-03-28 18:47:24

回答

2

在我們將返回創建的對象之前,因爲一切都被加載了 。

我有點懷疑,這是真的。如果您致電SaveChanges EF不執行查詢來加載導航屬性,無論您是否使用延遲加載。例如:

假設你有訂單導航參考客戶並在數據庫中已經使用id = 1。客戶現在您創建訂單(延遲加載啓用):

var order = context.Orders.Create(); 
order.CustomerId = 1; 
context.Orders.Add(order); 
context.SaveChanges(); 

bool isCustomerLoaded = context.Entry(order).Reference(o => o.Customer).IsLoaded; 

isCustomerLoadedfalse - 除非客戶1已經在上下文中,但隨後的財產,也沒有延遲加載(「關係修正」)來填充。當然,只要你訪問order.Customer它會被加載由於懶加載,但後來發生的並具有無關SaveChanges

如果你的代碼是一個好主意與否,取決於所使用的返回對象的方式,什麼消費者的期望。通常,沒有延遲加載的最接近延遲加載的替換是顯式加載,因爲兩個加載策略執行單個查詢來加載導航屬性。這當然意味着你必須在消費者端引入額外的代碼來加載屬性,而當你使用一個屬性並且在代理對象的重載屬性獲取器中發生查詢時,延遲加載「它只是起作用」。顯式加載如下所示:

context.Entry(order).Reference(o => o.Customer).Load(); 
// or for collections 
context.Entry(order).Collection(o => o.OrderItems).Load(); 

您必須在第一次訪問導航屬性的地方調用此函數。

如果你事先知道該對象從Create方法返回將所有需要導航屬性,那麼你可以加載它們與預先加載你提議的方式。但是與延遲加載相比,這肯定是數據庫訪問模式的一種變化:Eager加載只需要一個查詢來加載整個對象圖,但這是一個潛在的非常昂貴的查詢,DB中有很多JOIN和許多數據回。延遲加載和顯式加載會發出多個查詢,但返回的數據較少的簡單查詢。不考慮模型細節和做測量,不可能說什麼更好。

+0

你是對的,我在寫這篇文章時很匆忙,所以我對缺乏細節表示歉意。憑藉EF創建的代理,我可以訪問相關實體。這就是我在保存更改後訪問它們的原因。導航只在我請求時才加載。我提出了一個基礎設施(我將分享)在提交或一般查詢後包含特定實體。 – DDiVita 2012-03-28 21:40:37

+0

我更想知道其他用戶是否包含(在reget期間)或在提交後特別加載實體。通過引用()。Load,我想知道這是否會更好,然後像你說的那樣利用Include()。 – DDiVita 2012-03-28 21:40:56

+0

這是一篇很好的文章:http://thedatafarm.com/blog/data-access/the-cost-of-eager-loading-in-entity-framework/ – DDiVita 2012-03-28 21:44:32

相關問題