我正在尝试使用 System.Reflections
获得 DbSet<T>
从它的名字动态。
我现在有的是:
DbSet
姓名 DbSet
的 Type
存储在变量 我在尝试使用
dbcontext.Set<T>()
时遇到的问题方法,因为(这些是我迄今为止的尝试):<T>
时我的 DbSet
Type
,它向我抛出以下编译错误:"XXX is a variable but is used like a type"
Extension
您将在我的代码(我为了尝试获得 IQueryable<T>
而编写的)中找到的方法,它返回一个 IQueryable<object>
,不幸的是,这不是我想要的,因为当然当我尝试用进一步的反射来操作它时,它缺少原始类具有的所有属性...... 我究竟做错了什么?我怎样才能得到一个
DbSet<T>
?我的代码如下,当然,如果您需要更多信息、说明或代码片段,请告诉我。
我的 Controller 的方法 :
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);
}
}
编辑 已添加 打字机 的内码。
简而言之,此方法与
Type.GetType
的作用相同。 , 但在所有生成的程序集上搜索 Typepublic 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
更新该行。在输入中包含 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;
}
最佳答案
returns me an IQueryable<object>, I need an IQueryable<MyType>
好吧,那永远行不通。您的 IQueryable 不能是
IQueryable<MyType>
类型因为那意味着编译器需要知道什么 MyType
是的,那是不可能的,因为本练习的重点是在运行时决定这一点。也许知道这些对象实际上是
MyType
的实例就足够了。 ?如果没有,我想你已经把自己画到了一个角落里,你正试图弄清楚用什么油漆才能离开那里。退后一步,这可能不是技术问题。为什么需要这样做?为什么只在运行时知道类型和在编译时知道类型存在冲突?
您需要考虑您的要求,而不是技术细节。
关于c# - 通过实体类名动态获取 DbSet<T>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52721697/