San*_*oud 5 c# system.reflection entity-framework-core asp.net-core
我正在尝试使用它的名称动态System.Reflections获取DbSet<T>。
我现在有的是:
DbSet名DbSet的Type存储在可变在尝试使用该dbcontext.Set<T>()方法时,我面临的问题出现了,因为(这些是我迄今为止的尝试):
<T>my 时DbSet Type,它会引发以下编译错误:
“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);
//...
}
Run Code Online (Sandbox Code Playgroud)
类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);
}
}
Run Code Online (Sandbox Code Playgroud)
编辑添加TypeFinder的内部代码。
简而言之,此方法与 相同Type.GetType,但在所有生成的程序集上搜索 Type
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;
}
}
Run Code Online (Sandbox Code Playgroud)
根据评论中的要求更新,这是具体情况:
在我的数据库中,我有一些非常相似的表,所以我的想法是创建一个动态表更新方法,这对每个表都有好处,只需将表名,行的 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;
}
Run Code Online (Sandbox Code Playgroud)
Cha*_*nte -1
编辑:测试并工作:
public async Task<bool> MyMethod(string _type)
{
Type type = Type.GetType(_type);
var tableSet = _context.Set(type);
var list = await db.ToListAsync();
// do something
}
// pass the full namespace of class
var result = await MyMethod("Namespace.Models.MyClass")
Run Code Online (Sandbox Code Playgroud)
重要提示:您的 DbContext 需要声明 DbSet 才能工作!
public class MyContext : DbContext
{
public DbSet<MyClass> MyClasses { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6939 次 |
| 最近记录: |