有条件地在不同的DbContext.DbSet(作为模板参数)之间进行选择?

时间:2017-01-03 09:44:49

标签: c# entity-framework dbset

场景:我有一个现有的数据库供我操作。我转换数据并将它们映射到新表。 为了便于验证这些转换,我需要将它们放入单独的表中(以 Test _ 为前缀)。 但我仍然需要生产布局的功能。 因此,我必须以某种方式将 target-table 作为模板参数提供给transform-task(Process())。

// existing Models
public virtual class DataRecord1
{
    public Int32 Id { get; set; }
    ...
}
public virtual class DataRecord2
{
    public Int32 Id { get; set; }
    ...
}

// new Tables
public virtual class Test_DataRecord1 : DataRecord1
{}
public virtual class Test_DataRecord2 : DataRecord2
{}

public partial class DatabaseContext : DbContext
{
    public virtual DbSet<DataRecord1> DataRecord1 { get; set; }
    public virtual DbSet<DataRecord2> DataRecord2 { get; set; }
    // Test
    public virtual DbSet<Test_DataRecord1> Test_DataRecord1 { get; set; }
    public virtual DbSet<Test_DataRecord2> Test_DataRecord2 { get; set; }
}

转换可能会在多个函数中使用多个上下文实例,因此传递上下文不是一种选择。

public class ProcessTask
{
        // transform data
    public void Process()
    {
        using( var context = new DatabaseContext() )
        {
            context.Configuration.AutoDetectChangesEnabled = false;

            var data1 = context.DataRecord2
                .Where( ... )
                .ToList();
            var data2 = context.DataRecord1
                .Where( ... )
                .ToList();

            // operate and transform data 

            context.DataRecord1.AddRange( ... );

            context.ChangeTracker.DetectChanges();
            context.SaveChanges();
        }

        this.SubProcess();
    }

    private void SubProcess()
    {
        using( var context1 = new DatabaseContext() )
        using( var context2 = new DatabaseContext() )
        {
            // operate on the data
        }
    }
}

public static class Main()
{
    // current use:
    new ProcessTask().Process();
    // new functionality:
    new ProcessTask<Mode.Test>.Process(); // somehow change the task, so that Test_DataRecord is used
}

如何修改Process()以有条件地在DataRecordsTest_DataRecords之间进行选择?

1 个答案:

答案 0 :(得分:0)

您可以使用选择器方法参数化Process方法:

private void Process<T>(Func<DatabaseContext , DbSet<T>> selector)
    where T : DataRecord
{
    using( var context = new DatabaseContext() )
    {
        var dataRecords = selector(context);
        context.Configuration.AutoDetectChangesEnabled = false;

        var data = dataRecords
            .Where( ... )
            .ToList();

        // operate and transform data 

        dataRecords.AddRange( ... );

        context.ChangeTracker.DetectChanges();
        context.SaveChanges();
    }
}

您可以为不同的集合调用此方法:

public void ProcessDataRecord()
{
    Process(context => context.DataRecords);
}


public void ProcessTest_DataRecord()
{
    Process(context => context.Test_DataRecords);
}