日期:2014-05-20 浏览次数:21152 次
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
namespace LinqTest
{
// 产品信息
class Product
{
public int CategoryId { get; set; }
public string Name { get; set; }
public float Price { get; set; }
}
// 产品价格范围条件
class PriceCondition
{
public string Name { get; set; }
public float Min { get; set; }
public float Max { get; set; }
}
class Program
{
static List<Product> _products = new List<Product>(); //产品列表
static void Main(string[] args)
{
//添加产品数据
_products.Add(new Product() { CategoryId = 1, Name = "P1", Price = 50 });
_products.Add(new Product() { CategoryId = 2, Name = "P2", Price = 80 });
_products.Add(new Product() { CategoryId = 3, Name = "P3", Price = 100 });
_products.Add(new Product() { CategoryId = 2, Name = "P4", Price = 120 });
_products.Add(new Product() { CategoryId = 4, Name = "P5", Price = 200 });
//生成价格范围查询条件
List<PriceCondition> priceRange = new List<PriceCondition>();
priceRange.Add(new PriceCondition() { Name = "100元以下", Min = 0, Max = 100 });
priceRange.Add(new PriceCondition() { Name = "150~180元", Min = 150, Max = 180 });
//查询并输出
List<Product> result = Search("", new List<int> { 1, 2, 3 }, priceRange);
foreach(Product pdt in result)
Console.WriteLine("Name:{0}, CateId:{1}, Price:{2}", pdt.Name, pdt.CategoryId, pdt.Price);
Console.ReadLine();
}
//实现T-SQL效果: select * from product
// where Name like '%keyword%'
// and CategoryId in(1,2,3)
// and ((price<100) || (price>=150 and price<180))
static List<Product> Search(string keyword, List<int> cateIds, List<PriceCondition> priceRange)
{
Expression<Func<Product, bool>> expression = PredicateExtensions.True<Product>();
if (!string.IsNullOrEmpty(keyword))
expression = expression.And(p => p.Name.Contains(keyword));
if (cateIds != null && cateIds.Count > 0)
expression = expression.And(p => cateIds.Contains(p.CategoryId));
if (priceRange != null && priceRange.Count > 0)
{
foreach (PriceCondition pc in priceRange)
{
/////////////此处正确写法应该是什么呢?
if (pc.Max > 0)
expression = expression.Or(p => p.Price >= pc.Min && p.Price < pc.Max);
else
expression = expression.Or(p => p.Price >= pc.Min);
}
}
return _products.Where(expression.Compile()).ToList();
}
}
static class PredicateExtensions
{
public static Expression<Func<T, bool>> True<T>() { return f => true; }
public static Expression<Func<T, bool>> False<T>() { return f => false; }
public static Expression<Func<T, bool>> Or<T>(
this Expression<Func<T, bool>> expression1,
Expression<Func<T, bool>> expression2
)
{
var invokedExpression = Expression.Invoke(expression2, expression1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>(Expression.Or(expression1.Body, invokedExpression), expression1.Parameters);
}
public static Expression<Func<T, bool>> And<T>(
this Expression<Func<T, bool>> expression1,
Expression<Func<T, bool>> expression2
)
{
var invokedExpression = Expression.Invoke(expression2, expression1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>(Expression.And(expression1.Body, invokedExpression), expression1.Parameters);
}
}
}