IEnumerable<;的动态Linq表达式;int>;.包含(MemberExpression)

本文关键字:包含 gt MemberExpression int Linq lt 动态 IEnumerable 表达式 | 更新日期: 2023-09-27 18:29:16

我想使用Linq表达式树创建一个表达式来模拟:

List<int> ids = new List<int>();
// Fill ids with data
db.Where(a => ids.Contains(a.Id));

这就是我所得到的,但我仍然缺少一些东西:

MemberExpression me = Expression.Property(pe, typeof(T).GetProperty(property));
Expression callContains = Expression.Call(typeof(System.Linq.Enumerable), "Contains", new Type[] { me.Type }, me);

我如何才能正确地做我想做的事情?

IEnumerable<;的动态Linq表达式;int>;.包含(MemberExpression)

因为Contains是一个扩展方法,所以您还必须提供ids集合作为参数,在本例中,作为ConstantExpression

您的实现可能略有不同,但看起来有点像:

public static IQueryable<T> DynamicContains<T, TProperty>(
    this IQueryable<T> query, 
    string property, 
    IEnumerable<TProperty> items)
{
    var pe = Expression.Parameter(typeof(T));
    var me = Expression.Property(pe, property);
    var ce = Expression.Constant(items); 
    var call = Expression.Call(typeof(Enumerable), "Contains", new[] { me.Type }, ce, me);
    var lambda = Expression.Lambda<Func<T, bool>>(call, pe);
    return query.Where(lambda);
}
db.DynamicContains("Id", ids);

您可以添加对Mono.Sharp dll的引用,然后可以使用Evaluator类动态编译CSharp代码然后连接字符串以轻松创建linq查询然后编译它们它并不慢,而且很容易

在@ps-w-g答案的补充中,动态Not包含的是:

    public static IQueryable<T> DynamicNotContains<T, TProperty>(this IQueryable<T> query, string property, IEnumerable<TProperty> items)
    {        
        var pe = Expression.Parameter(typeof(T));
        var me = Expression.Property(pe, property);
        var ce = Expression.Constant(items);
        var call = Expression.Call(typeof(Enumerable), "Contains", new[] { me.Type }, ce, me);
        var lambda = Expression.Lambda<Func<T, bool>>(Expression.Not(call), pe);
        return query.Where(lambda);
    }
db.DynamicNotContains("Id", ids);