Question

I want to create an expression using the Linq Expression tree to simulate this:

List<int> ids = new List<int>();

// Fill ids with data

db.Where(a => ids.Contains(a.Id));

This is where I have gotten, but I am still missing something:

MemberExpression me = Expression.Property(pe, typeof(T).GetProperty(property));

Expression callContains = Expression.Call(typeof(System.Linq.Enumerable), "Contains", new Type[] { me.Type }, me);

How can I do what I want to do properly?

Était-ce utile?

La solution

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);

Autres conseils

You can add reference to Mono.CSharp dll, then you can use Evaluator class to compile csharp codes on the fly then concat strings to create linq queries easily then compile them it's not slow, and it is easy

In complementary of @p-s-w-g answer, the DynamicNotContains is :

    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);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top