关于如何使以下方法通用的建议

时间:2017-06-13 12:43:10

标签: c# .net generics

我有多种方法可以针对各种不同的对象执行以下操作,我想知道是否有一种方法可以使其具有足够的通用性,以便我不需要编写重复的代码。

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

1 个答案:

答案 0 :(得分: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);
 }