重视Linq技术_5

Building Query Expressions
//1、Compiling Expression Trees
Products.DeleteAllOnSubmit (Products.Where (p => p.ID == 999));
Products.InsertOnSubmit (new Product { ID = 999, Description = "Test", LastSale = DateTime.Now } );
SubmitChanges();
Product[] localProducts = Products.ToArray();
Expression<Func<Product, bool>> isSelling = 
	p => !p.Discontinued && p.LastSale > DateTime.Now.AddDays (-30);
IQueryable<Product> sqlQuery = Products.Where (isSelling);
IEnumerable<Product> localQuery = localProducts.Where (isSelling.Compile());

sqlQuery.Dump ("SQL Query");
localQuery.Dump ("Local Query, using same predicate");
//Compiling Expression Trees
Products.DeleteAllOnSubmit (Products.Where (p => p.ID == 999));
Products.InsertOnSubmit (new Product { ID = 999, Description = "Test", LastSale = DateTime.Now } );
SubmitChanges();

Product[] localProducts = Products.ToArray();

Expression<Func<Product, bool>> isSelling = 
	p => !p.Discontinued && p.LastSale > DateTime.Now.AddDays (-30);

IQueryable<Product> sqlQuery = Products.Where (isSelling);
IEnumerable<Product> localQuery = localProducts.Where (isSelling.Compile());

sqlQuery.Dump ("SQL Query");
localQuery.Dump ("Local Query, using same predicate");
//2、AsQueryable

 

void Main()
{
FilterSortProducts (Products).Dump ( "This query executes on SQL Server");
Product[] localProducts =
{
new Product { ID = 1, Description = "Local Product Test", LastSale = new DateTime (2007, 2, 3) }
};
FilterSortProducts (localProducts.AsQueryable()).Dump ( "The same query - executing locally");
}
IQueryable<Product> FilterSortProducts (IQueryable<Product> input)
{
return 
from p in input
where !p.Discontinued && p.LastSale < DateTime.Now.AddDays (-7)
orderby p.Description
select p;
}
//3、Examining an Expression Tree 
Expression<Func< string, bool>> f = s => s.Length < 5;

f.Body.NodeType.Dump ( "Body.NodeType");
(((BinaryExpression) f.Body).Right).Dump ( "Body.Right");

f.Dump ( "The whole expression tree");

//4、Building an Expression Tree 
 
ParameterExpression p = Expression.Parameter ( typeof ( string), "s");
MemberExpression stringLength = Expression.Property (p, "Length");
ConstantExpression five = Expression.Constant (5);
BinaryExpression comparison = Expression.LessThan (stringLength, five);
Expression<Func< string, bool>> lambda = Expression.Lambda<Func< string, bool>> (comparison, p);
Func< string, bool> runnable = lambda.Compile();
runnable ( "kangaroo")  .Dump ( "kangaroo is less than 5 characters");
runnable ( "dog")       .Dump ( "dog is less than 5 characters");
//kangaroo is less than 5 characters
//False
//dog is less than 5 characters
//True
 
//5、Extra-Using PredicateBuilder 

 

string[] keywords = { "Widget", "Foo", "Bar" };
var predicate = PredicateBuilder.False<Product>();
foreach ( string keyword in keywords)
{
string temp = keyword;
predicate = predicate.Or (p => p.Description.Contains (temp));
}
Products.Where(predicate).Dump( "Notice the multiple OR clauses in the SQL pane");

//6、Extra - Dynamic Ordering Sample

IQueryable query =           // The original unordered query
from p in Purchases
where p.Price > 100
select p;

string propToOrderBy = "Price";    // Try changing this to "Description" or "Date"
ParameterExpression purchaseParam = Expression.Parameter (typeof (Purchase), "p");
MemberExpression member = Expression.PropertyOrField (purchaseParam, propToOrderBy);
LambdaExpression lambda = Expression.Lambda (member, purchaseParam);
Type[] exprArgTypes = { query.ElementType, lambda.Body.Type };
MethodCallExpression methodCall =
Expression.Call (typeof (Queryable), "OrderBy", exprArgTypes, query.Expression, lambda);
IQueryable orderedQuery = query.Provider.CreateQuery (methodCall);
orderedQuery.Dump();

//7、Extra - Dynamic Ordering Sample - How it Words

// Let's break down the last example. We started with a simple unordered query (remember
// that the query does not evaluate at this point, thanks to deferred execution):
IQueryable<Purchase> query =            // The original unordered query
from p in Purchases
where p.Price > 100
select p;
// Here's the property or field name upon which we want to order:
string propToOrderBy = "Price";    // Try changing this to "Description" or "Date"

// The aim is to dynamically constuct the following:
// var orderedQuery = query.OrderBy (p => p.Price);
// Starting from the inside out, we start by creating the lambda expression, p => p.Price.
// To dynamically build a LambaExpression, we first create the parameter, in this case, p.
// Our parameter is of type Purchase, and is called "p":
ParameterExpression purchaseParam = Expression.Parameter ( typeof (Purchase), "p");
purchaseParam.Dump ( "purchaseParam");

// Next, we need to create "p.Price". The static method Expression.PropertyOrField returns
// a MemberExpression that finds a property or field with the given name:

MemberExpression member = Expression.PropertyOrField (purchaseParam, propToOrderBy);
member.Dump ( "member");

// With these two things, we build the LambdaExpression:
LambdaExpression lambda = Expression.Lambda (member, purchaseParam);
lambda.Dump ( "lambda");
lambda.ToString().Dump ( "lambda.ToString");

// We now need to wrap the lambda expression in a MethodCallExpression that
// references the Queryable.OrderBy method. For this, we call the static Expresion.Call
// method, which is overloaded especially to simplify the task of invoking methods
// that accept lambda expressions:

Type[] exprArgTypes = { query.ElementType, lambda.Body.Type };

MethodCallExpression methodCall =
Expression.Call (
typeof (Queryable),   // Type defining method we want to call
"OrderBy",                // Name of method to call
exprArgTypes,          // Generic argument types
query.Expression,     // First argument (the query expression body)
lambda);                // Second argument (the lambda expression)
methodCall.Dump ( "methodCall (notice all the work that Expression.Call does for us)");

// The final step is to create the new query, which calls the expression we've just
//created. For this, we use the Provider property exposed by the IQueryable interface,
// which returns an object upon which we call CreateQuery:

IQueryable orderedQuery = query.Provider.CreateQuery (methodCall);
// (Exactly the same thing happens when you ordinarily call Queryable.OrderBy;
// a good way to see this is to download Lutz Roeder's Reflector at
// http://www.aisto.com/roeder/dotnet/ and look at Queryable's OrderBy method).
// Here's the final result:
orderedQuery.Expression.ToString().Dump ( "The final result");

转载于:https://www.cnblogs.com/sanic/archive/2012/03/04/2379795.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值