2017-06-13 36 views
0

我有多種方法可以針對各種不同的對象執行以下操作,並且我想知道是否有一種方法可以使此通用性足以使我不需要編寫重複代碼。關於如何使下列方法通用的建議

public UpsertEntities(IList<MyEntity> entities) { 
     int totalImported = 0; 
     int totalRecords = entities.Count(); 


     var options = new ParallelOptions { MaxDegreeOfParallelism = 8 }; 



     var exceptions = new ConcurrentQueue<Exception>(); 
     var errors = new ConcurrentBag<string>(); 

     var batches = entities.ChunkBy(100); 


     foreach (var batch in batches) 
     { 


      var loopResult = Parallel.ForEach(batch, options, e => 
      { 
       try 
       { 
        using (var context = GetContext()) 
        { 
         context.SpecifiedEntityUpsert(e.Prop1, e.Prop2, e.Prop3, e.Prop4); 
        } 
        Interlocked.Increment(ref totalImported); 
       } 
       catch (Exception exception) 
       { 
        exceptions.Enqueue(exception); 

        errors.Add("Error Import " + e.Id + " " + exception.Message); 
       } 

       if (totalImported % 1000 == 0) 
        LoggingEngine.Instance.Info(Thread.CurrentThread.ManagedThreadId + " - " + " Imported " + totalImported + " of " + totalRecords + " records "); 
      }); 
     } 

     foreach (var err in errors) 
      LoggingEngine.Instance.Error(err); 
    } 

感謝您的任何建議。

所特有的各種方法的部分是方法名,在傳遞的參數和下面的代碼塊:

   using (var context = GetContext()) 
       { 
        context.SpecifiedEntityUpsert(e.Prop1, e.Prop2, e.Prop3, e.Prop4); 
       } 
+0

是什麼'SpecifiedEntityUpsert(e.Prop1,e.Prop2,e.Prop3,e.Prop4)',是那總是一樣的?你所有的類型都有'Prop1'到'Prop4'嗎? – Igor

+1

傳遞一個「Action 」來完成特定於實體的upsert。一般來說,確定具體位並用委託或虛擬方法將它們通用化。 –

+0

不,它是一個對每個實體都不同的實體框架存儲過程 – zSynopsis

回答

1

在代碼表明的唯一部分是特定於類型爲致電SpecifiedEntityUpsert。您可以將此方法從該方法中抽象出來,並將其委託給一個Action參數。

調用泛型方法

var myList = new List<MyEntity>(); 
UpsertEntities(myList, (context, e) => context.SpecifiedEntityUpsert(e.Prop1, e.Prop2, e.Prop3, e.Prop4)); 

泛型方法

// I made a guess that context is of type DbContext 
public UpsertEntities<T>(IList<T> entities, Action<DbContext, T> upsert) where T : class { 
    int totalImported = 0; 
    int totalRecords = entities.Count(); 

    var options = new ParallelOptions { MaxDegreeOfParallelism = 8 }; 

    var exceptions = new ConcurrentQueue<Exception>(); 
    var errors = new ConcurrentBag<string>(); 
    var batches = entities.ChunkBy(100); 

    foreach (var batch in batches) 
    { 
     var loopResult = Parallel.ForEach(batch, options, e => 
     { 
      try 
      { 
       using (var context = GetContext()) 
       { 
        // call to action parameter 
        upsert(context, e); 
       } 
       Interlocked.Increment(ref totalImported); 
      } 
      catch (Exception exception) 
      { 
       exceptions.Enqueue(exception); 
       errors.Add("Error Import " + e.Id + " " + exception.Message); 
      } 

      if (totalImported % 1000 == 0) 
       LoggingEngine.Instance.Info(Thread.CurrentThread.ManagedThreadId + " - " + " Imported " + totalImported + " of " + totalRecords + " records "); 
     }); 
    } 

    foreach (var err in errors) 
     LoggingEngine.Instance.Error(err); 
} 
+1

這正是我無法弄清楚的。非常感謝! – zSynopsis