如何获得Expression.Lambda <func <t,bool =“” >>泛型

时间:2018-10-08 23:21:06

标签: c# linq entity-framework-core

我有以下代码,我想将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())

这将起作用,但是会执行不希望的客户端评估。

1 个答案:

答案 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);
        }
    }
}