我正在尝试使用System.Reflections
得到一个DbSet<T>
动态地从它的名字。
我现在所拥有的是:
- The
DbSet
name
- The
DbSet
's Type
存储在变量上
我在尝试使用时遇到的问题出现了dbcontext.Set<T>()
方法,因为(这些是我迄今为止的尝试):
- When I try to assign to
<T>
my DbSet
Type
, it throws me the following compilation error:
“XXX 是一个变量,但像类型一样使用”
- 如果我尝试同时使用
Extension
您将在下面的我的代码中找到这些方法(我编写这些方法是为了尝试获得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 上下文集扩展
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);
}
}
EDIT Added 类型查找器的内部代码。
简而言之,该方法的作用与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;
}
}
UPDATE根据评论中的要求,这是具体案例:
在我的数据库中,我有一些彼此非常相似的表,因此我们的想法是创建一个动态表更新方法,该方法适用于每个表,只需将表名称、行的 ID 传递给此方法要更新的数据以及包含要更新的数据的 JSON。
因此,简而言之,我将对输入中给出的 DbSet 类型的表执行一些更新,用以下命令更新行ID==id
输入 JSON 中包含的数据,该数据将在 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;
}