System.Reflections
动态获取 DbSet<T>
。目前我已经拥有以下内容:-
DbSet
名称
- 存储在变量中的 DbSet
的 Type
当我尝试使用 dbcontext.Set<T>()
方法时,我遇到了问题,因为(这是我迄今为止的尝试):- 当我尝试将我的
DbSet
的 Type
分配给 <T>
时,它抛出以下编译错误:- 如果我尝试使用我在代码中找到的两个扩展方法(我制作这些方法是为了尝试获取"XXX 是一个变量,但被用作类型"
IQueryable<T>
),它会返回一个 IQueryable<object>
,不幸的是,这不是我要找的,因为当我尝试使用进一步的反射操作它时,它缺少所有原始类具有的属性...我做错了什么?我怎样才能得到一个
DbSet<T>
?以下是我的代码,如果需要更多信息、澄清或代码片段,请告诉我。 我的控制器方法:
public bool MyMethod (string t, int id, string jsonupdate)
{
string _tableName = t;
Type _type = TypeFinder.FindType(_tableName); //returns the correct type
//FIRST TRY
//throws error: "_type is a variable but is used like a type"
var tableSet = _context.Set<_type>();
//SECOND TRY
//returns me an IQueryable<object>, I need an IQueryable<MyType>
var tableSet2 = _context.Set(_type);
//THIRD TRY
//always returns me am IQueryable<object>, I need an IQueryable<MyType>
var calcInstance = Activator.CreateInstance(_type);
var _tableSet3 = _context.Set2(calcInstance);
//...
}
Class ContextSetExtension
public static class ContextSetExtension
{
public static IQueryable<object> Set(this DbContext _context, Type t)
{
var res= _context.GetType().GetMethod("Set").MakeGenericMethod(t).Invoke(_context, null);
return (IQueryable<object>)res;
}
public static IQueryable<T>Set2<T>(this DbContext _context, T t)
{
var typo = t.GetType();
return (IQueryable<T>)_context.GetType().GetMethod("Set").MakeGenericMethod(typo).Invoke(_context, null);
}
}
编辑 添加了 TypeFinder 的内部代码。
简而言之,该方法与 Type.GetType
相同,但在所有生成的程序集中搜索类型。
public class TypeFinder
{
public TypeFinder()
{
}
public static Type FindType(string name)
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
var result = (from elem in (from app in assemblies
select (from tip in app.GetTypes()
where tip.Name == name.Trim()
select tip).FirstOrDefault())
where elem != null
select elem).FirstOrDefault();
return result;
}
}
更新 根据评论的要求,这是具体的案例:
我的数据库中有一些非常相似的表,所以想法是创建一个动态表更新方法,对于每个表都很好用,只需将表名、要更新的行的ID和包含要更新数据的JSON传递给此方法。
因此,简而言之,我将执行一些在输入的DbSet类型表上的更新,使用输入中的ID==id
更新行,并将其内容解析为类型X(与dbset相同的对象)/转换为字典。
伪代码:
public bool MyMethod (string t, int id, string jsonupdate)
{
string _tableName = t;
Type _type = TypeFinder.FindType(_tableName); //returns the correct type
//THIS DOESN'T WORKS, of course, since as said above:
//<<throws error: "_type is a variable but is used like a type">>
var tableSet = _context.Set<_type>();
//parsing the JSON
var newObj = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonupdate, _type);
//THIS OF COURSE DOESN'T WORKS TOO
//selecting the row to update:
var toUpdate = tableSet.Where(x => x.Id == id).FirstOrDefault();
if(toUpdate!=null)
{
var newProperties = newObj.GetType().GetProperties();
var toUpdateProperties = toUpdate.GetType().GetProperties();
foreach(var item in properties)
{
var temp = toUpdateProperties.Where(p => p.Name==item.Name)
{
//I write it really in briefand fast, without lots of checks.
//I think this is enough, I hope
temp.SetValue(toUpdate, item.GetValue());
}
}
_context.SaveChanges();
}
return false;
}
public bool MyMethod<T>(int id, string jsonupdate) where T : class
。您会在该方法中做什么? - Ivan StoevIQueryable
或IQueryable<object>
,但是除了使用Dymanic LINQ,未类型化的DbContext
方法,反射,手动表达式树构建等方式外,您无法对其进行任何操作。 因此,请展示您的使用情况(伪代码),我们将为您提供最佳途径。 - Ivan Stoev