2011-11-24 53 views
3

我剛剛與一位同事討論Entity Framework更改跟蹤。我們終於想通了,我的上下文接口應該有實體框架跟蹤的開銷是多少?

IDBSet<MyPoco> MyThings { get; } 

而不是

IQueryable<MyPoco> MyThings { get; } 

,我的POCO也應該有它的所有屬性virtual

使用調試器,我們可以看到跟蹤對象,並且結果還包含代表我的實際POCO的代理。

如果我沒有我的POCO屬性virtual和使用IQueryable<>代替IDbSet<>有我的上下文接口我沒有得到任何的。

在這個例子中,我只查詢數據庫,但將來會希望通過實體框架來更新數據庫。

因此,爲了使我的生活在將來以這種代碼作爲參考時變得更加簡單,在我將永遠不會使用它們的情況下,跟蹤信息/代理在那裏有任何性能損失嗎?

回答

3

在EF中存在加固實體的性能損失。當您使用實體框架進行查詢時,EF將保留從數據庫加載的值的副本。單個Context實例也只跟蹤一個實體的單個實例。所以EF在創建實例之前必須檢查它是否已經有實體的副本(即,在幕後會有很多比較)。

因此,如果你不需要它,請避免它。你可以這樣做,如下所示。

IQueryable<MyPoco> MyThings { get { return db.MyThings.AsNoTracking(); } } 

關於Stages of Query Execution的MSDN頁面詳細列出了每個查詢執行步驟的相關成本。

編輯:

你不應該讓IDBSet<MyPoco> MyThings,因爲它告訴你的API,你的實體可以添加,更新和刪除的時候,其實你打算查詢數據的消費者。

2

在聲明爲虛擬的模型類中導航屬性,以暗示延遲加載功能,這意味着只有在需要時才需要導航屬性。就實體對象而言,主要目標是將來自數據庫的特定表記錄加載到來自DbContext的DbSet中。在這種情況下你不能使用IQueryable。另外,它對DataContext沒有任何意義。 IQueryable是一個完全不同的接口

+0

我實際上有一個接口,我編寫了我的linq查詢使用IQueryable <>。我在該接口的實現中也有IDBSet <>屬性,這些屬性作爲IQueryable返回。 –

+0

感謝您澄清延遲加載功能,我沒有考慮。 –