请教一个困扰很久的and or动态多条件组合查询的问题
- C# code
/// <summary> /// 产品价格范围条件 /// </summary> public class PriceCondition { public string Name { get; set; } public float Min { get; set; } public float Max { get; set; } } public class Demo { public static void Main() { List<PriceCondition> conditions = new List<PriceCondition>(); //价格范围条件 //添加条件 conditions.Add( new PriceCondition() { Name = "100元以下", Min = 0, Max = 100 }); conditions.Add( new PriceCondition() { Name = "151~180元", Min = 150, Max = 180 }); conditions.Add( new PriceCondition() { Name = "300元以上", Min = 300, Max = 0 }); Search(conditions, "关键字"); } //最终想实现类似T-SQL效果: select * from Product where Name like '%关键字%' and ((price<=100) || (price>150 and price<=180) || (price>300)) public List<Product> Search(List<PriceCondition> priceRange, string keywords) { var query = from p in Product.Table select p; if (!string.IsNullOrEmpty(keywords)) { query = from p in query where p.Name.Contains(keywords) select p; } if (priceRange.Count > 0) { foreach (var price in priceRange) { //这里该怎么写? } } return query.ToList(); } }[解决办法]
- C# code
using System;using System.Collections.Generic;namespace Test{ /// <summary> /// 产品价格范围条件 /// </summary> public class PriceCondition { public string Name { get; set; } public float Min { get; set; } public float Max { get; set; } } public class Demo { public static void Main() { List<PriceCondition> conditions = new List<PriceCondition>(); //价格范围条件 //添加条件 conditions.Add( new PriceCondition() { Name = "100元以下", Min = 0, Max = 100 }); conditions.Add( new PriceCondition() { Name = "101~200元", Min = 101, Max = 200 }); conditions.Add( new PriceCondition() { Name = "200元以上", Min = 200, Max = 0 }); Predicate<PriceCondition> macth = p => p.Name.Contains("1") && p.Max <= 33333; List<PriceCondition> list = Search(conditions, macth); foreach (PriceCondition price in list) { Console.WriteLine(price.Name); } Console.ReadKey(); } //最终想实现类似T-SQL效果: select * from Product where Name like '%关键字%' and ((price<=100) || (price>100 and price<=200) || (price>200)) public static List<PriceCondition> Search(List<PriceCondition> priceRange, Predicate<PriceCondition> macth) { return priceRange.FindAll(macth); } }}
[解决办法]
- C# code
void Main(){ List<PriceCondition> conditions = new List<PriceCondition>(); //价格范围条件 //添加条件 conditions.Add( new PriceCondition() { Name = "100元以下", Min = 0, Max = 100 }); conditions.Add( new PriceCondition() { Name = "151~180元", Min = 150, Max = 180 }); conditions.Add( new PriceCondition() { Name = "300元以上", Min = 300, Max = 0 }); Search(conditions, "关键字");} public List<Product> Search(List<PriceCondition> priceRange, string keywords) { Expression<Func<Product, bool>> expression = PredicateExtensions.True<Product>(); if (!string.IsNullOrEmpty(keywords)) { expression=expression.And(p=>p.Name.Contains(keywords)); } foreach (var price in priceRange) { expression=expression.Or(p=>(price.Min>0 && p.Price >price.Min) && (price.Max>0 && p.Price <price.Max)); } return Product.Table.Where(expression).ToList(); } /// <summary> /// 产品价格范围条件 /// </summary> public class PriceCondition { public string Name { get; set; } public float Min { get; set; } public float Max { get; set; } } // Product public class Product { public string Name{get;set;} public float Price{get;set;} } public 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); }}