> 通用,c#,linq,entity-framework-core"/>

首页 > 解决方案 > 如何获取 Expression.Lambda> 通用

问题描述

我有以下代码,我想将 Department 类型替换为泛型类型......

我很想换...

Expression.Lambda<Func<Department, bool>>(body, param)

经过..

 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 进行客户端评估。IE

Any(e => e.ToString == id.ToString())

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

标签: c#linqentity-framework-core

解决方案


我无法将方法转换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);
        }
    }
}

推荐阅读