我使用實體框架將特定對象的多個實例插入數據庫。我有一個單獨的對象上下文,我附上了幾個'產品'對象。我插入的對象與數據庫中的任何其他表都沒有關係。它純粹是一個獨立的實體。我正在使用'EFProf'工具來分析應用程序。實體框架批量插入導致選擇n + 1問題
當我調用'SaveChanges()'將我的'產品'實體持久化到SQL Server時,EFProf會警告我有'選擇N + 1'反模式。我不明白這是如何可能的,因爲我只是插入。我對'選擇N + 1'的理解是它涉及低效的對象檢索。我沒有檢索任何東西,只是插入。
當我檢查生成的SQL時,我發現Entity Framework已經爲我生成了一個select語句,它返回新插入對象的Id。這個select語句是爲我插入的每個實體執行的。這可能是選擇N + 1問題的原因嗎?如果是這樣,在SaveChanges()的單個調用中插入多個相同類型的實體時,如何避免這種反模式?
生成的SQL是如下:
insert [dbo].[Products]
([ProductName],
[ProductNum],
[Price],
[EntryDate],
[Description],
[Category],
[UnitsInStock])
values('TestProduct' /* @0 */,
0 /* @1 */,
0 /* @2 */,
'2011-07-09T17:14:49.00' /* @3 */,
'Category: Test Products - Name TestProduct' /* @4 */,
'Test Products' /* @5 */,
0 /* @6 */)
select [Id]
from [dbo].[Products]
where @@ROWCOUNT > 0
and [Id] = scope_identity()
這是一個非常有用的評論謝謝。我正在做一些NHibernate和Entity Framework的性能測試。這是我運行的第一個測試用例,我的NHibernate結果非常快(即使沒有批處理),我開始想知道我的代碼有什麼問題。就我所見,我的測試用例實現了相同的功能。當你說EF性能對於批量插入來說「非常糟糕」時,你是以什麼爲基礎的?我需要寫出我的結果,所以如果您有其他的研究或文章描述這個問題將非常有用。謝謝。 – JMc
這很容易。假設您在應用程序中創建了一些包含相關對象的對象。例如訂單與50個訂單項目。如果你有一個稱爲命令批處理的特性(如果使用正確的話,NHibernate也有這個功能),你將一次往返數據庫,它會包含51個插入(1個命令,50個項目)。如果您對EF執行相同的操作,它將按順序對數據庫執行51次往返操作,每次都包含一次插入。往返是幾乎所有可以做的操作中最慢的部分。 –