您的位置:首页 > 其它

[转]Dynamically Composing Expression Predicates

2008-03-25 22:16 211 查看
老外写的一个不错的扩展表达式的文章,原文地址:http://www.albahari.com/nutshell/predicatebuilder.html

Dynamically Composing Expression Predicates

Suppose you wanted to write a LINQ to SQL query that implemented a keyword-style. search. In other words, a query that returned rows whose description contained some or all of a given set of keywords.

We could proceed as follows:

IQueryable<Product> SearchProducts (params string[] keywords)

IQueryable<Product> SearchProducts (params string[] keywords)

using System;

using System.Linq;

using System.Linq.Expressions;

using System.Collections.Generic;

public static class PredicateBuilder

var predicate = PredicateBuilder.True <Product> ();


is just a shortcut for this:

Expression<Func<Product, bool>> predicate = c => true;

When you’re building a predicate by repeatedly stacking and/or conditions, it’s useful to have a starting point of either true or false (respectively). Our SearchProducts method still works if no keywords are supplied.

The interesting work takes place inside the And and Or methods. We start by invoking the second expression with the first expression’s parameters. An Invoke expression calls another lambda expression using the given expressions as arguments. We can create the conditional expression from the body of the first expression and the invoked version of the second. The final step is to wrap this in a new lambda expression.

More Examples

A useful pattern in writing a data access layer is to create a reusable predicate library. Your queries, then, consist largely of select and orderby clauses, the filtering logic farmed out to your library. Here's a simple example:

public partial class Product

public partial class Product

var newKids  = Product.ContainsInDescription ("BlackBerry", "iPhone");

var classics = Product.ContainsInDescription ("Nokia", "Ericsson")

.And (Product.IsSelling());

var query =

from p in Data.Products.Where (newKids.Or (classics))

select p;

The And and Or methods in boldface resolve to extension methods in PredicateBuilder.

An expression predicate can perform. the equivalent of an SQL subquery by referencing association properties. So, if Product had a child EntitySet called Purchases, we could refine our IsSelling method to return only those products that have sold a minimum number of units as follows:

public static Expression<Func<Product, bool>> IsSelling (int minPurchases)

...{


return prod =>


!prod.Discontinued &&


prod.Purchases.Where (purch => purch.Date > DateTime.Now.AddDays(-30))


.Count() >= minPurchases;


}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: