2017-01-03 19 views
0

私のコードロジックでは、まず複数のクエリで大量のレコードを削除しています。&一括挿入しています。Linq - 一括削除時にロックを防止する方法

using (var scope = new TransactionScope()) 
{ 
     using (var ctx = new ApplicationDbContext(schemaName)) 
     { 
     // Delete 
     foreach (var item in queries) 
     { 
      // Delete queries - more than 30 - optimized already 
      ctx.Database.ExecuteSqlCommand(item);     
     } 

     // Bulk Insert 
     BulkInsert(ConnectionString, "Entry", "Entry", bulkTOEntry); 
     BulkInsert(ConnectionString, "WrongEntry", "WrongEntry", bulkWrongEntry); 
     } 
     scope.Complete();   
} 

ここでの問題は、削除部分にある - :ここで

コードです。削除クエリは約10分かかります。これによりレコードがロックされるため、他のユーザーがレコードを取得または操作することはありません。

TransactionScopeに私のコードがありますが、削除中にエラーが発生した場合、トランザクション全体をロールバックします。

ストアドプロシージャを使用してチャンク内のレコードを削除しようとしましたが、TransactionScopeによってレコードがロックされているため、ここでは役に立ちませんでした。

レコードのロックを防止するにはどうすればよいですか?削除クエリの

サンプル: -

DELETE FROM [Entry] 
WHERE CompanyId = 1 
    AND EmployeeId IN (3, 4, 6, 7, 14, 17, 20, 21, 22,....100 more) 
    AND Entry_Date = '2016-12-01' 
    AND Entry_Method = 'I' 
+0

'TransactionScope'を削除すれば、 forループで実行しているSQLコマンドは何ですか? –

+0

これは、より多くの洞察を与えるかもしれません。http://stackoverflow.com/questions/12751258/batch-update-delete-ef5 – Eldho

+0

@FrankFajardoコードは、「TransactionScope」の有無にかかわらず同様に動作します。問題は、削除処理時のレコードのロックです。 – Anup

答えて

0

あなたはチャンクで従業員を削除する必要がある場合は、あなたが分割するために、このメソッドを使用することができ、この

public static List<IEnumerable<T>> Partition<T>(this IEnumerable<T> source, int length) 
     { 
      var count = source.Count(); 
      var numberOfPartitions = count/length + (count % length > 0 ? 1 : 0); 

      List<IEnumerable<T>> result= new List<IEnumerable<T>>(); 
      for (int i = 0; i < numberOfPartitions; i++) 
      { 
       result.Add(source.Skip(length*i).Take(length)); 
      } 

      return result; 
     } 

と従業員のリストを分割することができます小さいチャンクにリストアップして、一度に1つのチャンクを削除してください。他のユーザがチャンク間でテーブルを使用できるようにしてください。

関連する問題