2015-06-09 86 views
0

在對象列表上批量更新我想創建一個函數,該函數接受已設置其屬性的對象列表,並對它們進行批量更新或插入,僅對數據庫進行1次調用。使用EntityFramework 6和Linq

(UPDATE)這裏是工作的版本:

public static void BatchInsertProducts(IList<Product> productList) 
    { 
     using (var context = new DbContext()) 
     { 
      context.Products.AddRange(productList); 
      context.SaveChanges(); 
     } 
    } 

這是我在做任何更新和嘗試或基於ID的幾個項目的插入。我不認爲我可以在這裏使用的AddRange所以我這樣嘗試了,我得到一個錯誤:

public static void SaveMultipleProducts(IList<Product> productList) 
    { 
     using (var context = new DbContext()) 
     { 
      foreach (Account p in productList) 
      { 
       if (p.ID == 0) 
       { 
        context.Entry(p).State = EntityState.Added; 
        p.InsertUserId = "jtunney"; 
        p.InsertDate = DateTime.Now; 
       } 
       else 
       { 
        context.Entry(p).State = EntityState.Modified; 
        p.UpdateUserId = "jtunney"; 
        p.UpdateDate = DateTime.Now; 
       } 
      } 
      context.SaveChanges(); 
     } 
    } 
+0

正在您的productList中修改具有相同值的所有對象的相同屬性? –

+0

在某些情況下,所有的值都是相同的,但在其他情況下,所有的值都可能不同。比方說,我創建了一個簡單的productList,並以不同的價格向它添加3個產品,然後將其傳遞給我的BulkInsert函數。 linq能做這個操作嗎?或者我將不得不創建一個長字符串,並使用Database.SqlQuery函數直接將其傳遞給數據庫? – JTunney

+0

你爲什麼要在批處理中做到這一點? –

回答

2

刪除foreach循環,改變​​到IEnumerable<Product>

public static void BatchInsertProducts(IEnumerable<Product> productList) 
{ 
    using (var context = new DbContext()) 
    { 
     context.Products.AddRange(productList); 
     context.SaveChanges(); 
    } 
} 

一種方式做保存多個:

public static void SaveMultipleProducts(IEnumerable<Product> productList) 
{ 
    using (var context = new DbContext()) 
    { 
     foreach (Account p in productList) 
     { 
      p.InsertUserId="jtunney"; 
      p.InsertDate=DateTime.Now; 
      context.Entry(p).State=p.Id==0?EntityState.Added:EntityState.Modified; 
     } 
     context.SaveChanges(); 
    } 
} 

另一種方式:

public static void SaveMultipleProducts(IList<Product> productList) 
{ 
    using (var context = new DbContext()) 
    { 
     foreach (Account p in productList) 
     { 
      p.InsertUserId="jtunney"; 
      p.InsertDate=DateTime.Now; 
     } 
     // Add all records 
     context.Products.AddRange(productList); 

     // Handle updates 
     foreach(var p in productList.Where(p=>p.id!=0)) 
     { 
      context.Entry(p).State=EntityState.Modified; 
     } 
     context.SaveChanges(); 
    } 
} 
+0

好抓!我不能相信我在那裏留下了它,那是漫長的一天。你知道這是否會自動處理更新或插入?可以說,列表中的某些對象具有Ids,而其他對象則不具有。 – JTunney

+0

任何機會,你可以檢查我的最新更新,讓我知道如果這樣的事情可能只調用1 SaveChanges。 – JTunney

+0

真的應該創建一個新的問題而不改變它,否則其他人將無法從您的原始問題中學習,但更新我的答案。 –

1

這是沒有必要調用保存方法爲每個產品。如果您獲得產品並使用相同的DbContext進行保存,則只需調用Save一次,然後它將保存所有修改。

想象

List<Product> products = Context.Product.ToList(); 

foreach(var product in products) 
{ 
    product.Price = new Random().Next(); 
} 

Context.Product.SaveChanges(); 

此代碼修改列表中的所有產品的價格,但由於這樣的事實,我們使用相同的上下文檢索結果和EF implements Tracking保存一個修改調用SaveChanges就足夠了。

對於bulkInserts

使用的AddRange方法從實體框架http://www.entityframeworktutorial.net/EntityFramework6/addrange-removerange.aspx或者你可以嘗試這個庫https://efbulkinsert.codeplex.com/。我聽說過,但我從來沒有用過它

+0

你可以查看我對帖子頂部的功能所作的更新嗎?會是這樣的嗎?我覺得我的情況不同。我正在將我的函數傳遞給一個準備插入的productList。我不需要在我的上下文中進行任何更改。 – JTunney

+0

JTunney我用插入案例更新我的答案。 –

+0

添加範圍工作完美!非常感謝。我想這種事情會非常普遍,我會立即用谷歌搜索找到它。我更新了自己的帖子,給其他人一個例子。 – JTunney

相關問題