Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否有条件地在不同的DbContext.DbSet(作为模板参数)之间进行选择?_C#_Entity Framework_Dbset - Fatal编程技术网

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

C# 是否有条件地在不同的DbContext.DbSet(作为模板参数)之间进行选择?,c#,entity-framework,dbset,C#,Entity Framework,Dbset,场景:我有一个操作的现有数据库。我转换数据并将它们映射到新表中。 为了方便地验证这些转换,我需要将它们放在单独的表中(前缀为Test_389;)。 但我仍然需要生产布局的功能。 因此,我必须以某种方式将目标表作为模板参数提供给转换任务(Process()) //现有模型 公共虚拟类DataRecord1 { 公共Int32 Id{get;set;} ... } 公共虚拟类DataRecord2 { 公共Int32 Id{get;set;} ... } //新桌子 公共虚拟类测试\u DataRe

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

//现有模型
公共虚拟类DataRecord1
{
公共Int32 Id{get;set;}
...
}
公共虚拟类DataRecord2
{
公共Int32 Id{get;set;}
...
}
//新桌子
公共虚拟类测试\u DataRecord1:DataRecord1
{}
公共虚拟类测试\u DataRecord2:DataRecord2
{}
公共部分类DatabaseContext:DbContext
{
公共虚拟数据库集DataRecord1{get;set;}
公共虚拟数据库集DataRecord2{get;set;}
//试验
公共虚拟数据库集测试_DataRecord1{get;set;}
公共虚拟数据库集测试_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
}
公共类ProcessTask
{
//转换数据
公共程序()
{
使用(var context=new DatabaseContext())
{
context.Configuration.AutoDetectChangesEnabled=false;
var data1=context.DataRecord2
.其中(…)
.ToList();
var data2=context.DataRecord1
.其中(…)
.ToList();
//操作和转换数据
context.DataRecord1.AddRange(…);
context.ChangeTracker.DetectChanges();
SaveChanges();
}
这个.SubProcess();
}
私有无效子流程()
{
使用(var context1=new DatabaseContext())
使用(var context2=new DatabaseContext())
{
//对数据进行操作
}
}
}
公共静态类Main()
{
//当前用途:
新建ProcessTask().Process();
//新功能:
new ProcessTask.Process();//以某种方式更改任务,以便使用Test_DataRecord
}

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

您可以使用选择器方法对
过程
方法进行参数化:

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

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

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

DatabaseContext
指定为函数参数并没有帮助,因为
Process()
可以使用数据库上下文的多个实例,也可以调用其他函数。您没有提供任何详细信息,说明如何实际确定是要使用
Test\u DataRecord
还是常规
DataRecord
?将
DatabaseContext
作为函数参数没有帮助,因为
Process()
可能会使用数据库上下文的多个实例或调用其他函数。您没有提供任何详细信息,说明您实际上是想使用
测试\u数据记录还是常规
数据记录。谢谢。有没有办法不指定模板约束(或者只为所有不同的
IProcessTask
实现指定一次)?因为我可能会在function@user5997884:您可以将查询参数化,并在方法中添加一部分,然后在
过程中多次调用它。这样,您只需创建一次上下文,并且只需使用一个事务。但是,由于您有多个数据库集,因此在某些时候必须拆分查询。@user5997884:您可以定义一个接口并将其用作约束。看看这个答案:是的,但这在现有的代码库中并不舒服,因为我需要为所有类中的几千个属性创建接口。另外,我需要在更改EF型号时使其保持最新,不是吗?我想没有简单快捷的方法可以做到这一点,因为您的基类,所以这里不需要接口。谢谢。有没有办法不指定模板约束(或者只为所有不同的
IProcessTask
实现指定一次)?因为我可能会在function@user5997884:您可以将查询参数化,并在方法中添加一部分,然后在
过程中多次调用它。这样,您只需创建一次上下文,并且只需使用一个事务。但是,由于您有多个数据库集,因此在某些时候必须拆分查询。@user5997884:您可以定义一个接口并将其用作约束。看看这个答案:是的,但这在现有的代码库中并不舒服,因为我需要为所有类中的几千个属性创建接口。另外,我需要在更改EF型号时使其保持最新,不是吗?我想没有简单快捷的方法可以做到这一点,因为您的基类,所以这里不需要接口。
public void ProcessDataRecord()
{
    Process(context => context.DataRecords);
}


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