我有以下代码,我想将Department类型替换为通用类型...
我想替换...
Expression.Lambda<Func<Department, bool>>(body, param)
by ..
Expression.Lambda<Func<T, bool>>(body, param)
我知道我必须使用反射,但是我所拥有的只是装箱为对象的域模型类。
我可以获得对象及其类型名称,但是我很难用通用类型替换硬编码类型Department。
我无法将方法Exists
转换为Exists<T>
,因为调用该方法时我不知道<T>
是什么。我只有那个东西。
public bool Exists(object id, object source, Type type)
{
var param = Expression.Parameter(type, "e");
var body = Expression.Equal(Expression.Property(param, "Id", Expression.Constant(id));
var where = Expression.Lambda<Func<Department, bool>>(body, param);
var context = new DataContext();
var dbSet = context.Set<Department>();
return dbSet.AsNoTracking().Any(where);
}
对于dbset案例,我尝试了以下代码
public static IQueryable<object> Set (this DbContext context, Type type)
{
return IQueryable<object>)context.GetType().GetMethod("Set")?.MakeGenericMethod(type).Invoke(context, null);
}
然后替换...
var dbSet = context.Set<Department>();
通过
var dbSet = context.Set(type);
这似乎可行,我拥有正确的dbset,但是where子句存在一些问题,这些问题会导致运行时错误。
我要实现的目标是避免EF Core进行客户端评估。即
Any(e => e.ToString == id.ToString())
这将起作用,但是会执行不希望的客户端评估。
答案 0 :(得分:1)
我无法将方法
Exists
转换为Exists<T>
,因为调用该方法时我不知道<T>
是什么。我只有object
。
这就是泛型将有助于动态lambda表达式生成的地方。
public class MyEntity
{
public int Id { get; set; }
}
public class muckingabout
{
public bool Exists<T>(T myentity) where T: MyEntity
{
var type = typeof(T);
//e =>
var param = Expression.Parameter(type, "e");
//e => e.Id
var property = Expression.Property(param, "Id");
var value = Expression.Constant(myentity.Id);
//e => e.Id == myentity.Id
var body = Expression.Equal(property, value);
var lambda = Expression.Lambda<Func<T, bool>>(body, param);
using (var context = new DbContext())
{
var dbSet = context.Set<T>();
return dbSet.AsNoTracking().Any(lambda);
}
}
}