"
The major reason for changing the PredicateDescription was that we were getting a lot of request to broaden the range of possible predicates that we could support as well as to extend our dynamic query support in general with projections, grouping and aggregate operators. Much of this is described here: http://drc.ideablade.com/xwiki/bin/view/Documentation/dynamic-queries - http://drc.ideablade.com/xwiki/bin/view/Documentation/dynamic-queries
One of the most obvious changes was that we realized that a ‘property name’ was just the simplest example of the idea of ‘projecting’ data out of a type. Another example was a ‘nested property name’, i.e. customer.Address.City or even a projection that involves a method call i.e. “customer.Orders.First().Freight”. We also wanted to use this same concept not just in the PredicateDescription but also more generally anywhere within a dynamic query where a projection was needed. We decided to call our implementation of this a ProjectionSelector. So now a PredicateDescription can use a ProjectionSelector on either side of a FilterOperator, the new dynamic ‘Select’ operator uses ProjectionSelectors to describe selection criteria, the dynamic ‘GroupBy’ operator uses ProjectionSelectors to describe grouping criteria.
In making these changes we were able to keep all of our PredicateDescription constructors completely backward compatible but did remove ctors from the CompositePredicateDescription in favor of extension methods or static methods on the PredicateBuilder class to perform the same task. This change was simply to minimize the number of ways of accomplishing the same task. So you can still compose your CompositePredicateDescription in either of the following ways.
var expr1 = new PredicateDescription(typeof(Product), "UnitPrice", FilterOperator.IsGreaterThanOrEqualTo, 24);
var expr2 = new PredicateDescription(typeof(Product), "Discontinued", FilterOperator.IsEqualTo, true);
var expr3 = new PredicateDescription(typeof(Product), "Id", FilterOperator.IsNotEqualTo, 0);
var expr123 = expr1.And(expr2).And(expr3);
or
var expr123 = PredicateBuilder.And(expr1, expr2, expr3);
There are, of course ‘Or’ variants of each of these apis.
"
below are some other examples showing other uses for a ProjectionSelector:
"
Compare two properties of an object
var ps1 = new ProjectionSelector("CompanyName");
var ps2 = new ProjectionSelector("City"); var pd = new PredicateDescription(ps1, FilterOperator.StartsWith, ps2);
Using Projections with a method call.
var rootQuery = EntityQuery.Create(typeof(Customer), _em1);
var ps = new ProjectionSelector( "OrderSummaries.FirstOrDefault().Freight", "freight" );
var query = query.Select(pps);
Complex query with aggregate ‘Any’ operator
// dynamic query for -> OrderSummaries.Where( os => os.OrderDetails.Any( od => od.Product.ProductName.Contains(“Chai’) && od.UnitPrice > 3)
var pd1 = new PredicateDescription(typeof(OrderDetail), "Product.ProductName", FilterOperator.Contains, "Chai");
var pd2 = new PredicateDescription(typeof(OrderDetail), "UnitPrice", FilterOperator.IsGreaterThanOrEqualTo, 3);
var pd3 = pd1.And(pd2);
var baseQuery = EntityQuery.Create(typeof(OrderSummary), _em1);
var pd4 = new PredicateDescription(typeof(OrderSummary), "OrderDetails", FilterOperator.Any, pd3);
var finalQuery = baseQuery.Where(pd4);
Silvio.