日期:2014-05-20 浏览次数:21025 次
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); } } }