Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.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# 只有在运行时才知道类名的查询上下文_C#_Entity Framework_Generics - Fatal编程技术网

C# 只有在运行时才知道类名的查询上下文

C# 只有在运行时才知道类名的查询上下文,c#,entity-framework,generics,C#,Entity Framework,Generics,我正在考虑创建一段代码,允许我根据字符串类名动态查询数据库 我想在这里简要概述一下: 我的背景: public class MyContext : DbContext { public DbSet<Foo> Foos {get;set;} public DbSet<Bar> Bars {get;set;} } 我曾尝试使用一种通用方法来实现这一点,如: //method in context public IEnumerable<T> Get

我正在考虑创建一段代码,允许我根据字符串类名动态查询数据库

我想在这里简要概述一下:

我的背景:

public class MyContext : DbContext
{
    public DbSet<Foo> Foos {get;set;}
    public DbSet<Bar> Bars {get;set;}
}
我曾尝试使用一种通用方法来实现这一点,如:

//method in context
public IEnumerable<T> GetGenericData<T>() where T : Type
{
    return context.Set<T>();
}

//call in repo
context.GetGenericData<Type.GetType("Foo")>();
现在的问题是,
var数据
是一个DbSet。我需要能够将其转换为在运行时定义的类型列表。有没有一个简单的解决方案可以做到这一点,因为我不能简单地执行
var data=context.GetGenericData(myType).toList()

编辑2: 为了给这个问题添加更多的上下文,我正在考虑创建一段代码来从文件中读取数据库表列表,例如,获取这些表中的数据并将其序列化为XML文件

基本上,我会有一个包含以下内容的文件:

Foo
Bar
MoreStuff

然后读取,并将Foo表中的所有数据导出到名为Foo.xml的xml文件中。还必须做相反的事情,从xml文件中读取数据并将其导入数据库

您的方法是可靠的,但是,我会重新考虑
IEnumerable
方法,因为它不支持
包含
和其他特定于数据库的操作。

如果您在运行时不知道实体类型,但有类型名称,您可以借助反射类型.GetType(string typeName)按名称获取类型,并使用DbContext.Set重载,比如->DbSet.Set(类型)

详情请浏览

更新:

void Main()
{
    var typeMapping = new Dictionary<Type, Func<object, dynamic>>(){
        {typeof(A), a => (A)a}
    };
    var array = new[]{new A(){ o = new Object() },new A(){ o = new Object() },new A(){ o = new Object() },new A(){ o = new Object() },};    
    var objectArray = array.OfType<object>();
    objectArray.Select(a => typeMapping[a.GetType()](a)).Dump();

}

class A{
    public object o {get;set;}
}
并使用类似XmlSerializer的

var fileStream = File.OpenWrite("someFilePathName");
new XmlSerializer().Serialize(fileStream, data);
就是这样!它会起作用,因为CLR会准确地知道DbSet集合中的项的类型。而且您不必强制转换到任何类型。然后XmlSerializer将完成实体序列化器集合所需的所有工作,并将其写入到文件流中。另外一件事是添加一些检查,并为IDisposable实例添加使用块

更新3:

DbSet不能用ToList强制转换为确切的类型,因为其思想是避免在实体的编译时使用类型。因此,这里是加载数据并将其强制转换为对象以继续操作的思想

Set(typeof(TableBase)).Load();
var collectionToExport = Set(typeof (TableBase)).Local.Cast<object>().ToList();
Set(typeof(TableBase)).Load();
var collectionToExport=Set(typeof(TableBase)).Local.Cast().ToList();
总而言之:

var type = Type.GetType("Foo");
context.Set(type).Load();
var collectionToExport = context.Set(type).Local.Cast<object>().ToList();
var fileStream = File.OpenWrite("someFilePathName");
new XmlSerializer().Serialize(fileStream, data);
var type=type.GetType(“Foo”);
context.Set(type).Load();
var collectionToExport=context.Set(type).Local.Cast().ToList();
var fileStream=File.OpenWrite(“someFilePathName”);
新的XmlSerializer().Serialize(文件流、数据);

您的方法很好。不知道您是否可以帮助我进行上述编辑是的,但如果您已经描述了,我无法理解。无论如何,您可以将结果集合中的项强制转换为特定类型(entityType),但这将是一些硬代码。如果提供用例的完整描述,可能很容易建议:)评论您的最新更新,问题是我无法调用GetGenericData返回值上的
.ToList()
,非常感谢!比我想象的容易多了
var fileStream = File.OpenWrite("someFilePathName");
new XmlSerializer().Serialize(fileStream, data);
Set(typeof(TableBase)).Load();
var collectionToExport = Set(typeof (TableBase)).Local.Cast<object>().ToList();
var type = Type.GetType("Foo");
context.Set(type).Load();
var collectionToExport = context.Set(type).Local.Cast<object>().ToList();
var fileStream = File.OpenWrite("someFilePathName");
new XmlSerializer().Serialize(fileStream, data);