In addition to using LINQ syntax, we can also build queries dynamically at runtime using Expressions
. For example, the following code will create two method expressions, one for the where
clause, and one for the order by
clause:
ParameterExpression param = Expression.Parameter(typeof(Product), "p"); Expression left = Expression.Property(param, typeof(Product).GetProperty("UnitPrice")); Expression right = Expression.Constant((decimal)100.00, typeof(System.Nullable<decimal>)); Expression filter = Expression.GreaterThanOrEqual(left, right); Expression pred = Expression.Lambda(filter, param); IQueryable products = db.Products; Expression expr = Expression.Call(typeof(Queryable), "Where", new Type[] { typeof(Product) }, Expression.Constant(products), pred); expr = Expression.Call(typeof(Queryable), "OrderBy", new Type[] { typeof(Product), typeof(string) }, expr, Expression.Lambda(Expression.Property(param, "ProductName"), param)); IQueryable<Product> query = db.Products.AsQueryable().Provider.CreateQuery<Product>(expr); foreach (var p in query) Console.WriteLine("Product name: {0}", p.ProductName);
To build the first expression, we first created a left
expression, and a right
expression. Then, we used them to create a filter
expression. The predicate
expression is then created based on this filter expression.
As the second expression takes the first expression as an argument, it expands the first expression to include an order by
expression.
The statement with the CreateQuery
method is the one that creates the query dynamically, according to the expressions that we have created before this statement. And, of course, the query won't get executed until the foreach
statement is executed.
Before running this program, you need to add the following using
statement to the beginning:
using System.Linq.Expressions;
The output of the above code looks as shown in the following image: