2016-05-13 169 views
-1

我有一個函數,它使用EF,但它的工作太慢... 你知道任何方式,如何提高此功能的性能?性能的實體框架

public static void SaveCombiners() 
    { 
     using (var db = new IP_dbEntities()) 
     { 
      db.COMBINERs.RemoveRange(db.COMBINERs); 
      foreach (var type1 in EventTypesList) 
      { 
       foreach (var type2 in EventTypesList) 
       { 
        db.COMBINERs.Add(new COMBINER() 
        { 
         EVENTS_TYPE = db.EVENTS_TYPE.Single(type => type.event_type == type1), 
         EVENTS_TYPE1 = db.EVENTS_TYPE.Single(type => type.event_type == type2), 
         combine_status = _eventTypesCombinerCollection[type1][type2].Value == true ? "+" : "-" 
        }); 
       } 
      } 
      db.SaveChanges(); 
     } 
    } 
+0

寫純SQL和使用'db.Database.ExecuteSqlQuery(SQL,則params).ToListAsync();' –

+0

爲什麼你寫2 「的foreach」 1名名單? –

+0

是的,+1,所以你可能會發現更好的是做一組讀,然後做你的寫作......而不是每次你寫一個閱讀! –

回答

3

應始終使用的AddRange 添加。 Add方法每次調用add方法時都會嘗試DetectChanges,而AddRange只調用一次。

public static void SaveCombiners() 
{ 
    using (var db = new IP_dbEntities()) 
    { 
     db.COMBINERs.RemoveRange(db.COMBINERs); 

     List<COMBINER> list = new List<COMBINER>(); 

     foreach (var type1 in EventTypesList) 
     { 
      foreach (var type2 in EventTypesList) 
      { 
       list.Add(new COMBINER() 
       { 
        EVENTS_TYPE = db.EVENTS_TYPE.Single(type => type.event_type == type1), 
        EVENTS_TYPE1 = db.EVENTS_TYPE.Single(type => type.event_type == type2), 
        combine_status = _eventTypesCombinerCollection[type1][type2].Value == true ? "+" : "-" 
       }); 
      } 
     } 

     db.COMBINERs.AddRange(list); 
     db.SaveChanges(); 
    } 
} 

這就是說,你面臨另一個性能問題。

每個要刪除或添加的記錄都需要數據庫往返行程。因此,如果您刪除10,000條記錄並添加5,000條記錄,則需要15,000次數據庫往返,這非常緩慢。

免責聲明:我的項目Entity Framework Extensions

這個庫允許實體框架內進行批量操作的所有者。您只需將「SaveChanges」更改爲「BulkSaveChanges」即可顯着提高性能。

public static void SaveCombiners() 
{ 
    using (var db = new IP_dbEntities()) 
    { 
     db.COMBINERs.RemoveRange(db.COMBINERs); 
     // ... code.. 
     db.COMBINERs.AddRange(list); 

     db.BulkSaveChanges(); 
    } 
} 
0

RemoveRange的AddRange太慢,嘗試ExecuteSqlCommand

MyContext.Database.ExecuteSqlCommand("Delete from MyTable"); 
+0

如果需要刪除所有行,則最好在這裏使用「TRUNCATE TABLE [TableName]」命令 – AndrewSilver

+0

@AndrewSilver - 也許,但可能不是。截斷不會觸發觸發器,因此應該爲DDL而不是DML保留。 – PhillipH

+0

它的確定,我使用foreach兩次,因爲我的2維字典中有相同的行和列名稱 –