2016-05-13 5 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

あなたは1つのリストのために2 "foreachの" を書くのはなぜ? –

+0

ええええええええええええええええええれば、一組の読み取りを行い、次にあなたの書き込みをするのではなく、書き込みを行うたびに読むことです! –

答えて

3

あなたはいつもAddRangeが終わっ追​​加使用する必要があります。 Addメソッドは、AddRangeが1回だけ呼び出されるたびにDetectChangesを試行します。

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レコードを追加すると、データベースのラウンドトリップ回数は15000回と非常に遅くなります。

免責事項:私はEntity Framework Extensions

このライブラリは、Entity Frameworkの内バルク操作を実行できるようにするプロジェクトの所有者です。 "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

RemoveRangeAddRange遅すぎ、ExecuteSqlCommand

を試してみてください
MyContext.Database.ExecuteSqlCommand("Delete from MyTable"); 
+0

すべての行を削除する必要がある場合は、ここで "TRUNCATE TABLE [TableName]"コマンドを使用する方が良いでしょう。 – AndrewSilver

+0

@AndrewSilver - おそらく、そうではないかもしれません。 Truncateはトリガーを起動しないため、DMLではなくDDL用に予約する必要があります。 – PhillipH

+0

それはOKです、私はforeachを2回使用しています、私の2次元辞書には同じ行と列の名前があります –

関連する問題