It's just syntactic sugar that gets better than you :)
The problem is that Contains really not a method on DataQuery<T> - it is a static method in System.Linq.Queryable . The C # compiler handles this for you using extension methods, but it's just a C # compiler - this is not a feature of IL, it is a feature of C #. Therefore, when you manipulate expression trees or emit raw IL, you must handle this yourself:
private Expression<Func<T, bool>> Contains<T, V> (string property, IQueryable<V> values, T item) { ParameterExpression pe = Expression.Parameter(item.GetType(), "c"); Expression columnNameProperty = Expression.Property(pe, property); var someValueContain = Expression.Constant(values, values.GetType()); var convertExpression = Expression.Convert(columnNameProperty, typeof(V)); Expression expression = Expression.Call ( ( ((Expression<Func<bool>>) (() => Queryable.Contains(default(IQueryable<V>), default(V))) ) .Body as MethodCallExpression).Method, someValueContain, convertExpression ); return Expression.Lambda<Func<T, bool>>(expression, pe); }
I would avoid using dynamic in LINQ queries, since you are using it, this is no better than having an IEnumerable<object> , and if you want it to always be Guid anyway, just do it generic :)
This method assumes that any type of column can be converted to the type of elements you enumerate, of course, of course, but it will work for any type, not just Guid .
However, this will not solve the second problem that you have - it is quite explicit. The passage you listed has too many items to pass. If your LINQ provider does not have a better way of passing values, you will have to resort to splitting the query into several separate queries, each of which, for example, 1000 elements, and then merging the results. Unless, of course, my guess is correct, and the values you pass are actually also a request - in this case, the code should work fine.
EDIT:
The best way to find the right MethodInfo is with a set of methods like this:
public static MethodInfo Method<TR>(Expression<Func<TR>> expression) { return (expression.Body as MethodCallExpression).Method; } public static MethodInfo Method<T1, TR>(Expression<Func<T1, TR>> expression) { return (expression.Body as MethodCallExpression).Method; }
(autogenerated in the same way as actual delegates Func<...> )
This makes it easier to obtain information about this method:
Method((IQueryable<T> queryable, T item) => queryable.Contains(item))
Or, conversely, (so as not to create all possible overloads):
Method(() => default(IQueryable<T>).Contains(default(T)))