2011-09-10 113 views
1

如果你已經有一個集合,有沒有什麼辦法可以插入多條沒有循環的記錄?如果您在循環之外提交,那麼獲得的性能好處不大。通過對象插入多條記錄

我有一個上下文和ObjectSet<Type>。我也有一個Type的集合,我想要交換或連接或相交,或者你有什麼表中的內容。換句話說,我不想從以下着手:

foreach (Type r in Collection) 
{ 
    Context.ObjectSet.Add(r); 
} 
Context.SaveChanges(); 
+0

不太知道我理解你的第二個段落,但..任何僞代碼,解釋你的意思? – scartag

+0

它好像你想要一個批量插入。是這樣嗎? – TMB

+0

我認爲一個批量插入是我所追求的。我直觀地認爲add方法對可枚舉的方法不僅僅是一個add方法。如果它涉及到數據庫,則每多次添加一次調用SaveChanges不等於批量插入。 –

回答

2

您必須始終使用循環。在諸如AddCollectionAddRange之類的方法中不會有任何性能優勢,因爲這些方法通常適用於一些性能優化,其中內部集合擴展了整個範圍,並且僅複製而不是爲每個Add調用擴展集合。 AddObject做的更多,然後將數據傳遞給一些內部集合,所以它仍然必須逐個處理實體。

如果您想自行優化數據庫插入的性能,您必須轉移到另一個解決方案,因爲EF沒有任何批處理或批量數據修改。每個記錄都作爲單獨的插入單獨傳遞到數據庫。

+0

謝謝。總的來說,當我從EF開始時,我所面臨的問題是在哪裏容納將基於許多其他內容改變很多表中的許多記錄的邏輯。你的回答表明把這些東西拉到記憶裏可能不是這樣。 –

1

你可以嘗試創建一個擴展方法做循環和增加。 見下文。

public static class AddHelper 
{ 


    public void AddAll(this ObjectSet<T> objectSet,IEnumerable<T> items) 
    { 

     foreach(var item in items) 
     { 
      objectSet.AddObject(item); 

     } 

    } 

} 

然後你可以使用下面的代碼。

IEnumerable<EntityName> list = GetEntities(); //this would typically return your list 
Context.ObjectSet.AddAll(list); 
+0

謝謝 - 那會至少隱藏那個邏輯 –

0

我正在尋找相同類型的解決方案。

我還沒有找到一種方法來直接與EF做,但有一種方法可以做到這一點。如果創建一個接受DataTable作爲參數的存儲過程,則可以使用實體上下文執行PROC並將該表作爲參數傳遞。

當您處理數千或數百萬條記錄時,這比循環傳遞給數據庫的每條記錄要好得多。

Passing Table Valued Parameters to SQL Server Stored Procedures.