2017-05-30 22 views
1

私のC#プログラムでは、Entity Frameworkを使用してローカルSQL ServerデータベースをQuickBooksデータと同期させています。 QuickBooksからデータを取得することに問題はないようです。しかし、私は、エンティティの一括コミットを行うときに戸惑いに遭っています。Entity Framework - バッチSaveChangesの処理方法

現在、構成可能な数のエンティティでDataContextを構築してから、エンティティをバッチでコミットしています。これまでバッチは失敗していませんでしたが、もしあればどうなりますか?これと戦うための私のアイデアは、バッチを繰り返し処理し、各エンティティを一度に1つずつ提出し、コミットの失敗の原因となっているものを記録することです。

しかし、SaveChanges()を使用しているときはすべてまたは何も問題には見えないため、データコンテキストでこれを行う方法はありません。私が達成しようとしていることに対処する方法はありますか、まったく違う方法で失敗に対処するべきでしょうか?ここで

は、私は現在、ケースには、あなたがそれを見てみたいしているコードです:...それはあなたがから回復したい例外に依存

int itemsCount = 0; 
int itemsSynced = 0; 
int itemsFailed = 0; 

ArrayList exceptions = new ArrayList(); 

int batchSliceCount = Properties.Settings.Default.SyncBatchSize; //Getting the max batch size from the settings 
int index = 1; //Index used for keeping track of current batch size on data context 
List<Customer> currentBatch = new List<Customer>(); // List to hold curent batch 

db = new DataContext(DatabaseHelper.GetLocalDatabaseConnectionString()); 

foreach (var customer in QBResponse.customers) 
{ 
    itemsCount++; 

    try 
    { 
     string debugMsg = "Saving Customer with the Following Details....." + Environment.NewLine; 
     debugMsg += "ListId: " + customer.CustomerListId + Environment.NewLine; 
     debugMsg += "FullName: " + customer.FullName + Environment.NewLine; 
     int progressPercentage = (itemsCount * 100)/opResponse.retCount; 
     UpdateStatus(Enums.LogLevel.Debug, debugMsg, progressPercentage); 

     var dbCustomer = db.Customers.FirstOrDefault(x => x.CustomerListId == customer.CustomerListId); 

     if (dbCustomer == null) 
     { 
      // customer.CopyPropertiesFrom(customer, db); 
      Customer newCustomer = new Customer(); 
      newCustomer.CopyCustomer(customer, db); 
      newCustomer.AddBy = Enums.OperationUser.SyncOps; 
      newCustomer.AddDateTime = DateTime.Now; 
      newCustomer.EditedBy = Enums.OperationUser.SyncOps; 
      newCustomer.EditedDateTime = DateTime.Now; 
      newCustomer.SyncStatus = true; 

      db.Customers.Add(newCustomer); 
      currentBatch.Add(newCustomer); 
     } 
     else 
     { 
      //dbCustomer.CopyPropertiesFrom(customer, db); 
      dbCustomer.CopyCustomer(customer, db); 
      dbCustomer.EditedBy = Enums.OperationUser.SyncOps; 
      dbCustomer.EditedDateTime = DateTime.Now; 
      dbCustomer.SyncStatus = true; 
      currentBatch.Add(dbCustomer); 
     } 

     try 
     { 
      if (index % batchSliceCount == 0 || index == opResponse.customers.Count()) //Time to submit the batch 
      { 
       UpdateStatus(Enums.LogLevel.Information, "Saving Batch of " + batchSliceCount + "Customers to Local Database"); 
       db.SaveChanges(); 
       itemsSynced += currentBatch.Count(); 
       currentBatch = new List<Customer>(); 
       db.Dispose(); 
       db = new DataContext(DatabaseHelper.GetLocalDatabaseConnectionString()); 
      } 
     } 
     catch (Exception ex) 
     { 
      string errorMsg = "Error occured submitting batch. Itterating and submitting one at a time. " + Environment.NewLine; 
      errorMsg += "Error Was: " + ex.GetBaseException().Message + Environment.NewLine + "Stack Trace: " + ex.GetBaseException().StackTrace; 
      UpdateStatus(Enums.LogLevel.Debug, errorMsg, progressPercentage); 

      //What to do here? Is there a way to properly iterate over the context and submit a change one at a time? 
     } 
    } 
    catch (Exception ex) 
    { 
     //Log exception and restart the data context 
     db.Dispose(); 
     db = new DataContext(DatabaseHelper.GetLocalDatabaseConnectionString()); 
    } 

    Thread.Sleep(Properties.Settings.Default.SynchronizationSleepTimer); 
    index++; 
} 
+0

確かに、私は何をしたいのですか...。SaveChangesに関する例外があった場合、少なくとも変更がまだ利用できるように、ログに内容を書き込もうとします。しかし、EFはこの権利を守ることになっています。それは「追跡」能力です。私は回復の前に仕事をする必要がなかったので、ここで大声で考えています。 –

答えて

0

あなたの場合接続が中断された場合に再試行する方法を探しているだけで、実行方法DbExecutionStrategyに基づいて実行すると、CodeProjectのように特定のエラーが発生した場合に再試行します。

+0

私はタイムアウトに対処するための実行戦略を使用していることを知っています。私はまだ実装していませんが、開発ロードマップ上にあります。私はキー違反などの例外にもっと関心を持っています(I.E. SQL Serverではコミットされているエンティティバッチが拒否されています)。 – Stephen

+0

再試行がキー違反エラーを解決する方法がないため、ストアに安全な状態にしようとする前にバッチを自分で検証することをお勧めします – user1859022

関連する問題