特别请教@q107770540,关于动态组合条件查询的问题
特别请教@q107770540,以下为完整控制台代码,粘贴后可以直接运行。
按照查询条件,理想的输出产品应为P1、P2、P4,但这里的结果却不对,请问为什么呢?谢谢!
- C# code
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); } }}
[解决办法]
以前问过。http://topic.csdn.net/u/20120814/17/6a25779f-d16e-465a-8fdf-2d0c1ecbc7e9.html
应该不会有P4
[解决办法]
http://www.cnblogs.com/whitewolf/archive/2010/08/02/1790390.html
文章链接在这,我想仔细看看这篇文章,你可以解决你的问题的