The*_*ads 5 c# generics entity-framework
我正在寻找创建一段代码,以允许我根据字符串类名称动态查询我的数据库.
我想要的简要概述:
我的背景:
public class MyContext : DbContext
{
public DbSet<Foo> Foos {get;set;}
public DbSet<Bar> Bars {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
通过我的设置,我通过做基本的查询这个上下文context.Foos.Where(...) ,我基本上想做同样的事情,但不是必须.Foos在编译时知道该部分,而是希望它在运行时完成.
逻辑上我想要的是:
var results = context."ClassName".Where(...)
Run Code Online (Sandbox Code Playgroud)
我尝试使用通用方法执行此操作,例如:
//method in context
public IEnumerable<T> GetGenericData<T>() where T : Type
{
return context.Set<T>();
}
//call in repo
context.GetGenericData<Type.GetType("Foo")>();
Run Code Online (Sandbox Code Playgroud)
我不确定我是否会走这条路.理想情况下,我希望得到一个解决方案,这意味着我不必沿着SQL路线前进
编辑:一直在努力,我已经到了这一步.
//method in context
public DbSet GetGenericData(Type _type)
{
return context.Set(_type);
}
//calling like
var data = context.GetGenericData(myType);
Run Code Online (Sandbox Code Playgroud)
现在的问题是,它var data是一个DbSet.我需要能够将其转换为在运行时定义的Type列表.有没有一个简单的解决方案来做到这一点,因为我不能简单地做到这一点var data = context.GetGenericData(myType).toList()
编辑2:为问题添加更多上下文,我正在寻找创建一段代码来从文件中读取数据库表的列表,例如,获取这些表中的数据并将其序列化为XML文件.
基本上我会有一个包含以下内容的文件:
Foo
Bar
MoreStuff
Run Code Online (Sandbox Code Playgroud)
然后将读取哪个,并将Foo表中的所有数据导出到名为Foo.xml的xml文件中.还必须反过来,它从xml文件中读取数据并将其导入数据库
如果您在运行时不知道实体类型但具有类型名称,则可以通过反射Type.GetType(字符串typeName)获取类型名称,并使用DbContext.Set重载 - > DbSet Set.Set(Type type)
有关详细信息,请访问http://msdn.microsoft.com/en-us/library/gg679544(v=vs.113).aspx
更新:
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;}
}
Run Code Online (Sandbox Code Playgroud)
这是来自LinqPad的样本.你的问题是关于动态编程,我无法理解目的但仍然如此.在此粘贴中,您必须为所有实体类型定义类型映射,例如CLR类型和转换操作,它们返回所需类型的引用.例如,数组变量是目的,objectArray是您的数据.
UPADATE2:
使用SerializableAttribute标记您的实体类型 http://msdn.microsoft.com/en-us/library/system.serializableattribute(v=vs.110).aspx 比调用ToList或ToArray扩展名一样
var data = context.GetGenericData(myType).Tolist();
Run Code Online (Sandbox Code Playgroud)
并使用XmlSerializer序列化它
var fileStream = File.OpenWrite("someFilePathName");
new XmlSerializer().Serialize(fileStream, data);
Run Code Online (Sandbox Code Playgroud)
而已!它会起作用,因为CLR会确切知道DbSet集合中的项目类型.你不需要施展任何东西.然后XmlSerializer将完成序列化器收集实体所需的所有工作,并将其写入流,即文件流.还有一件事是添加一些检查并为IDisposable实例添加使用块.
UPDATE3:
DbSet无法转换为与ToList完全类型,因为这个想法是避免在实体的编译时使用类型.所以这里是加载数据并将其转换为对象以继续操作的想法
Set(typeof(TableBase)).Load();
var collectionToExport = Set(typeof (TableBase)).Local.Cast<object>().ToList();
Run Code Online (Sandbox Code Playgroud)
和所有在一起:
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);
Run Code Online (Sandbox Code Playgroud)