List<string> citiesIWillVisit = new List<string>(){ "London", "Berlin", "Prague" }; var customersAround = nwContext.Customers.Where<Customers>(cx => citiesIWillVisit.Contains(cx.City));
List<object> citiesIWillVisit = new List<object>(){ "London", "Berlin", "Prague" };
//Create the Northwind Client Context northwindContext nwContext = new northwindContext( new Uri("http://ServiceEndPoint/Northwind.svc") ); var customersAround = from cx in nwContext.Customers where cx.City == "London" || cx.City == "Berlin" || cx.City == "Prague" select cx; foreach (Customers coHabitant in customersAround) { System.Console.WriteLine(coHabitant.ContactName); }
nwContext.Customers.Where<Customers>(cx => cx.City == "London")
Parameter : "cx"Left Hand Side Of Expression : cx.CityConstant : "London"
//The parameter expression containing the Entity Type //cx ParameterExpression param = Expression.Parameter(typeof(Customers), "cx"); //The Left Hand Side of the Filter Expression //cx=> cx.City MemberExpression left = Expression.Property(param, "City"); //The constant to compare against ConstantExpression constant = Expression.Constant("London") //Build the Filter //cx=> cx.City == "London" Expression.Equal( left , constant ) //Build the LambdaExpression to pass to the Where Method //.Where(cx=> cx.City == "London") var lambda = Expression.Lambda<Func<Customers, bool>>(filterExpression, param); //Execute the Filter var customersAround = nwContext.Customers.Where<Customers>(lambda);
Expression filterPredicate = null; foreach (var id in set) { //Build a comparison expression which equates the Id of the Entity with this value in the IDs list // ex : e.Id == 1 Expression comparison = Expression.Equal(left, Expression.Constant(id)); //Add this to the complete Filter Expression // e.Id == 1 or e.Id == 3 filterPredicate = (filterPredicate == null) ? comparison : Expression.Or(filterPredicate, comparison); }
static Expression<Func<Customers, bool>> ContainedInSet(IEnumerable Set, string Property, Type EntityType) { //The Filter Predicate that contains the Filter criteria Expression filterPredicate = null; //The parameter expression containing the Entity Type ParameterExpression param = Expression.Parameter(EntityType, "l"); //The Left Hand Side of the Filter Expression Expression left = Expression.Property(param, Property); //Build a Dynamic Linq Query for finding an entity whose ID is in the list foreach (var id in Set) { //Build a comparision expression which equats the Id of the ENtity with this value in the IDs list // ex : e.Id == 1 Expression comparison = Expression.Equal(left, Expression.Constant(id)); //Add this to the complete Filter Expression // e.Id == 1 or e.Id == 3 filterPredicate = (filterPredicate == null) ? comparison : Expression.Or(filterPredicate, comparison); } //Convert the Filter Expression into a Lambda expression of type Func<Lists,bool> // which means that this lambda expression takes an instance of type EntityType and returns a Bool var lambdaFilterExpression = Expression.Lambda<Func<Customers, bool>>(filterPredicate, param); return lambdaFilterExpression; }
PingBack from http://net.blogfeedsworld.com/?p=22343
While the 'LINQ Ninja' moniker is something that Phani completely made up on the spot and I actively
Shouldn't it be possible to pass in the property to be filtered as an expression rather than a string, so that you retain intellisense support and compile-time validation? As in:
nwContext.Customers.IsIn<Customers>(citiesIWillVisit, (c) => c.City);
The extension method signature would become:
public static IQueryable<T> IsIn<T>(this IQueryable<T> query, IEnumerable Set, Expression<Func<T, object>> Left)
(Probably better to use IQueryable rather than DataServiceQuery, just in case you wanted to re-use this with another Linq provider that doesn't support Set-based 'In' clauses)
And in the method you'd do:
ParameterExpression param = Left.Parameters.Single();
to bind your outer filter parameter with the inner property selector.
Hi Joe,
That sounds like a neat idea.
I shall try your suggestion and update the code snippet later
Telerik has a range of controls that work with ADO.NET Data Services as the data source . Take a look
Hi,
Is there any way to extend the above method to use a Contains expression (ultimately translating to a 'substringof' query) instead of an Equals?
I am able to generate the expression I want by manually building the query string - enumerate around the enumerable set or'ing together 'substringof('{0}', property)' - but can't seem to generate the expression that equates to this query.
Cheers,
Ian
As an extension to explained in the last blog post dealing with Set based filter operations in our client
Very cool extension method, thanks for sharing!
Noticed a small typo:
ParameterExpression param = propertyExpression.Paramters.Single();
should read:
ParameterExpression param = propertyExpression.Parameters.Single();
Fixed, thanks for correcting this Scott!
Long time since no comments. Just to add that this solution is not working with Guids, but i fixed that by adding generic set and converting expression to specific S type ;)
public static IQueryable<T> IsIn<T, S>(this IQueryable<T> query, IEnumerable<S> Set, Expression<Func<T, Object>> propertyExpression)
{
//The Filter Predicate that contains the Filter criteria
Expression filterPredicate = null;
//The parameter expression containing the Entity Type
//Get Key Property
//The Left Hand Side of the Filter Expression
Expression left = propertyExpression.Body;
//Build a Dynamic Linq Query for finding an entity whose ID is in the list
foreach (var id in Set)
//Build a comparision expression which equats the Id of the ENtity with this value in the IDs list
// ex : e.Id == 1
Expression comparison = Expression.Equal(Expression.Convert(left, typeof(S)), Expression.Constant(id));
//Add this to the complete Filter Expression
// e.Id == 1 or e.Id == 3
filterPredicate = (filterPredicate == null) ? comparison : Expression.Or(filterPredicate, comparison);
}
//Convert the Filter Expression into a Lambda expression of type Func<Lists,bool>
// which means that this lambda expression takes an instance of type EntityType and returns a Bool
var filterLambdaExpression = Expression.Lambda<Func<T, bool>>(filterPredicate, param);
return query.Where(filterLambdaExpression);