请教一个困扰很久的and or动态多条件组合查询的问题

时间:2022-08-27 05:37:17

/// <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();
}
}

5 个解决方案

#1


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);
        }
    }
}


请教一个困扰很久的and or动态多条件组合查询的问题

#2



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);
}
}

#3


我喜欢楼主这种提问方式,给出的关键代码和类定义 
并清晰描述清楚自己要什么

如果能给出些Product的测试数据就更好了

#4


非常感谢两位!@q107770540 的方法应该是最合适的,谢谢!

#5


引用 3 楼  的回复:
我喜欢楼主这种提问方式,给出的关键代码和类定义 
并清晰描述清楚自己要什么

如果能给出些Product的测试数据就更好了


请问,原理是什么呢?或者发给我相应的文章链接,谢谢!

#1


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);
        }
    }
}


请教一个困扰很久的and or动态多条件组合查询的问题

#2



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);
}
}

#3


我喜欢楼主这种提问方式,给出的关键代码和类定义 
并清晰描述清楚自己要什么

如果能给出些Product的测试数据就更好了

#4


非常感谢两位!@q107770540 的方法应该是最合适的,谢谢!

#5


引用 3 楼  的回复:
我喜欢楼主这种提问方式,给出的关键代码和类定义 
并清晰描述清楚自己要什么

如果能给出些Product的测试数据就更好了


请问,原理是什么呢?或者发给我相应的文章链接,谢谢!