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