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

Adchun 2012-08-28 11:25:13

/// <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();
}
}
...全文
509 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
SocketUpEx 2012-08-28
  • 打赏
  • 举报
回复
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);
}
}
}



Adchun 2012-08-28
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

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

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

请问,原理是什么呢?或者发给我相应的文章链接,谢谢!
Adchun 2012-08-28
  • 打赏
  • 举报
回复
非常感谢两位!@q107770540 的方法应该是最合适的,谢谢!
q107770540 2012-08-28
  • 打赏
  • 举报
回复
我喜欢楼主这种提问方式,给出的关键代码和类定义
并清晰描述清楚自己要什么

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

q107770540 2012-08-28
  • 打赏
  • 举报
回复

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

8,497

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 LINQ
社区管理员
  • LINQ
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧