2017-01-03 1 views
0

In meiner Code-Logik, zuerst lösche ich große Datensätze mit mehreren Abfragen & dann Bulk einfügen. HierLinq - Wie Sperren bei Massenlöschung zu verhindern

ist der Code: -

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();   
} 

Das Problem hierbei ist im Lösch Teil. Die Löschabfragen dauern ungefähr 10 Minuten. Dies führt dazu, dass die Datensätze gesperrt werden, sodass die anderen Benutzer keine Datensätze abrufen oder bearbeiten können.

Ich habe meinen Code im TransactionScope, als ob es einen Fehler beim Löschen gibt, dann wird die gesamte Transaktion zurückgesetzt.

Ich habe versucht, die Datensätze in Chunks durch gespeicherte Prozeduren zu löschen, aber das hat hier nicht geholfen, da immer noch die Datensätze aufgrund des TransactionScope gesperrt sind.

Wie verhindert man Sperren auf den Datensätzen?

Probe von Delete-Abfragen: -

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

Sie sagen, wenn Sie das 'TransactionScope' entfernen, dass Ihr Code schneller läuft? Was ist der SQL-Befehl, den Sie in Ihrer for-Schleife ausführen? –

+0

Dies könnte Ihnen mehr Einblick geben http://stackoverflow.com/questions/12751258/batch-update-delete-ef5 – Eldho

+0

@FrankFajardo Code läuft ähnlich mit oder ohne 'TransactionScope'. Das Problem besteht darin, die Datensätze zum Zeitpunkt des Löschvorgangs zu sperren. – Anup

Antwort

0

, wenn Sie die Mitarbeiter in Klumpen löschen müssen, können Sie die Liste der Mitarbeiter geteilt mit diesem

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; 
     } 

können Sie diese Methode verwenden, die spalten Liste zu kleinen Brocken und lösche sie einen Brocken nach dem anderen Benutzer kann die Tabelle zwischen Brocken verwenden

Verwandte Themen