I have some code that currently builds up an In statement in SQL. I build an expression, it returns;
value(generic(list[T])).Contains(x => x.Id)
This works fine, so if I have a list of objects;
public class ObjectToSearch
{
public int IdToSearchOn {get;set;}
}
And I want to search for ids 1, 2, 3, it works just fine. My SQL query is great.
Now, I have a need to search a list of nested objects, so I might have;
public class ParentObjectToSearch
{
public IEnumerable<ObjectToSearch> Objects {get;set;}
}
So, looking at some code I found (How do I create an expression tree calling IEnumerable<TSource>.Any(...)?) I figured I could adapt the method, and wrap a call to Any or All, and it would work. This worked great, until I actually came to test against the database, I get;
Cannot compare elements of type 'System.Collections.Generic.ICollection`1'. Only primitive types (such as Int32, String, and Guid) and entity types are supported.
var collectionType = GetIEnumerableImpl( forCollection.Type );
Type elementType = collectionType.GetGenericArguments( )[0];
MethodInfo method = BaseFilter.GetType( ).GetMethod( "FilterWith" );
MethodInfo genericMethod = method.MakeGenericMethod( new[] { elementType } );
return (genericMethod.Invoke( BaseFilter, null ) as LambdaExpression);
FilterWith is the method I'm calling on the original filter, in the hope of getting back my expression. So, it looks like my inner expression is being evaluated incorrectly when combined with the outer expression. What I'm basically aiming for is (I believe);
x => x.Collection.Contains( y => new { 1, 3, 3}.Contains( y.Id));
If I test the inner filtering separately, it works fine, so I assume it's just how I'm trying to combine the elements, and if I try and use Contains instead of Any or All, I still get the same error.
I've put Entity Framework in the tags, because this is being evaluated as expressions against an entity set, and someone may have experience of doing this.
Update Having a night to think about it, I think I have a better question;
How do I build a Where expression, so I can build;
x => x.Collection.Where( y => new[] { 1, 3 }.Contains( y.Id)).Count( ) > 0