2012-03-08 104 views
1

我們的應用存在巨大的性能問題,我們從不同的系統收集數據並將其保存在我們的數據庫中,以便稍後生成一些報告。使用EF4.2批量插入

我們使用實體框架4.2和DbSets,有沒有這樣做批量插入,然後Add方法有關DbSet每個實體的更好的辦法?因爲有與添加邏輯

oneThousandCustomers.Foreach(c => context.Customers.Add(c)); //This will take a minute 
context.SaveChanges(); //This takes under a second 

巨大的性能問題,我想add方法是引擎蓋下做大量的查找等之類的東西,但我只是想批量插入這些數據。可能嗎?

回答

1

好吧,所以這裏的交易是,當你將項目添加到集合時,EF在場景下做了大量的工作。

在性能方面真正的大的事情是,它調用DetectChanges()自動上列舉了整個對象圖中的每個add命令。

這意味着,如果你有這正在由目前的EF上下文跟蹤大量的項目,這將導致一些非常嚴重的性能問題。

下面有一些提示,以提高性能,作爲比較,我可以插入1000個沒有FK的相當簡單的實體EF在1/2第二下。

  • 確保您使用的是新的EF上下文實例爲您的查詢, 這將確保您的圖形變化很小,因此增加會 相當快。爲的DbContext

代碼

  • 打開自動變化檢測來關閉自動檢測更改

    context.Configuration.AutoDetectChangesEnabled = false; 
    

    當禁用AutoDetectChanges你需要小心一點,因爲它意味着大部分EF的automagic被關閉,所以你可能會感到奇怪,特別是如果你正在使用導航屬性或正在更新現有的實體。要解決這些問題,請在調用SaveChanges之前調用DetectChanges。這會降低性能,並且不需要簡單的添加操作,因此在您的示例中,如果沒有此操作,您可能會離開。

    這個這個MSDN文章談到,(注意:即使它的EF 5的相同4)http://msdn.microsoft.com/en-us/library/gg696177%28v=vs.103%29.aspx

  • +0

    我們使用CQRS框架,並且每個請求注入上下文,更改上下文的行爲有點危險,因爲不能保證命令邏輯的其他部分在更改上下文行爲後不會使用上下文。 – Anders 2012-03-08 10:00:03

    +0

    如果您想要EF的好處,性能是危險的並且涉及妥協,那麼您需要處理性能問題或手動管理環境以優化性能。如果你不想這樣做,你也想要性能,那麼不要使用EF。但是,我對CQRS,消息傳遞和批量導入以及EF(對於查詢和寫入)都做了完全相同的事情,並且它工作正常。 – 2012-03-08 11:16:31

    +0

    我們選擇這一個,因爲它很容易改變我們現有的代碼。所有的單元測試和場景測試都是綠色的,所以它看起來像在工作!謝謝! – Anders 2012-03-09 08:40:21

    0

    您可以使用LinqEntityDataReader對實體集合,這將提高性能進入此鏈接描述您的應用程序執行SqlBulkCopy的。

    +0

    將檢查出來,謝謝! – Anders 2012-03-08 10:03:54