6

我想使用 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);

我怎样才能正确地做我想做的事?

4

3 回答 3

15

Because Contains is an extension method, you'll also have to provide the ids collection as a parameter, in this case, as a ConstantExpression.

Your implementation might be slightly different, but it would look a bit like this:

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);
于 2013-08-28T15:31:41.167 回答
0

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

于 2013-08-28T15:46:31.487 回答
0

作为@pswg 答案的补充,动态包含是:

    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);
于 2017-06-06T13:40:34.760 回答