Print Page | Close Window

Dynamic Query from two predicates.

Printed From: IdeaBlade
Category: DevForce
Forum Name: DevForce 2010
Forum Discription: For .NET 4.0
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=2758
Printed Date: 15-Oct-2026 at 1:29pm


Topic: Dynamic Query from two predicates.
Posted By: sarmaad
Subject: Dynamic Query from two predicates.
Date Posted: 13-Jun-2011 at 5:48am
I have got a following query:

Expression<Func<Contact, bool>> c2 = (col => col.CompanyContacts.AsQueryable().Any(p => p.Company.CompanyName.Contains("some_name")));

ITypedEntityQuery query = EntityQuery<Contact>.Create(typeof(Contact), Manager).Cast<Contact>().Where(c2).OrderBySelector(selector).Skip(skip).Take(take);

That works perfectly fine. Unfortunatelly when I try to split the first expression into two like this:

var exp1 = (Expression<Func<CompanyContact, bool>>)(p => p.Company.CompanyName.Contains("some_name"));
Expression<Func<Contact, bool>> c2 = (col => col.CompanyContacts.AsQueryable().Any(exp1));

I got a nasty serialization error:

Type 'System.Linq.Expressions.Expression`1[System.Func`2[DomainModel.CompanyContact,System.Boolean]]' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute.  If the type is a collection, consider marking it with the CollectionDataContractAttribute.  See the Microsoft .NET Framework documentation for other supported types.

The point of splitting the query is simple - I want to generate the inner part from IPredicateDescription.

Thanks in advance.



Replies:
Posted By: kimj
Date Posted: 13-Jun-2011 at 2:52pm
That is an ugly exception.  It looks like we have a problem with the use of the nested Queryable.Any() inside of the predicate, but it's going to take more research to determine the underlying problem and how we might fix it.
 
For now, if you're able to use PredicateDescriptions for both clauses, you can do something like the following:
 
var baseQuery = EntityQuery<Contact>.Create(typeof(Contact), Manager);
var pd1 = new PredicateDescription(typeof(CompanyContacts), "Company.CompanyName", FilterOperator.Contains, "some_name");
var pd2 = new PredicateDescription(typeof(Contact), "CompanyContacts", FilterOperator.Any, pd1);
var query = baseQuery.Where(pd2).OrderBySelector(selector).Skip(skip).Take(take);
 


Posted By: sarmaad
Date Posted: 14-Jun-2011 at 3:11am
Thank you - that works!

One remark - pd1 cannot be a CompositePredicateDescription, it generates exception otherwise.


Posted By: pk55
Date Posted: 25-Jun-2011 at 2:11pm
Is the requirement that the ANY filter operator only have one, single predicate description a bug or is that by design? 
 
Seems kind of limited if you can't filter a child collection on more than one property and then filter the parent based on it having a child that matches that condition.


Posted By: kimj
Date Posted: 27-Jun-2011 at 1:08pm
The problem with the CompositionPredicateDescription when used with FilterOperator.Any is actually a bug.  The intention with our dynamic query API has been to provide support for common LINQ methods.  The Queryable.Any LINQ method, which FilterOperator.Any is trying to proxy, supports either no arguments or a single predicate, and we translated that "predicate" a bit too strictly.  


Posted By: pk55
Date Posted: 27-Jun-2011 at 3:57pm

Any idea when this would be fixed to allow a composite?



Posted By: DenisK
Date Posted: 27-Jun-2011 at 4:00pm
Hi pk55;

The patch that I'm sending you will contain this fix as well.



Print Page | Close Window