linq to sql的多条件动态查询确实是一件头痛的事情,用表达式树或反射方法要写一大堆代码,有时候想想与其这么复杂,还不如回到手动sql拼接的年代,但是技术总是向前发展的,终归还是要在linq上解决这一问题,无意在网上发现一个还算比较简单的办法,分享一下:
void ShowData()
{
using (DBDataContext db = new DBDataContext(Database.ConnectionString))
{
Expression<Func<T_Bargin, bool>> expr = n => GetCondition(n);
var _query = db.T_Bargins.Where<T_Bargin>(expr.Compile()).Select(b => new { b.F_Money, b.F_Name });
foreach (var item in _query)
{
Response.Write(item.F_Name + " " + item.F_Money.ToString() + "<br/>");
}
}
}
//得到合同金额大于6000,或合同名称中包含"江华"字的条件
private bool GetCondition(T_Bargin _Table)
{
bool _result = false;
decimal _MinMoney = 6000;
if (_MinMoney > 0)
{
_result |= _Table.F_Money >= _MinMoney;
}
string _Name = "江华";
if (!String.IsNullOrEmpty(_Name))
{
_result |= _Table.F_Name.Contains(_Name);
}
return _result;
}
{
using (DBDataContext db = new DBDataContext(Database.ConnectionString))
{
Expression<Func<T_Bargin, bool>> expr = n => GetCondition(n);
var _query = db.T_Bargins.Where<T_Bargin>(expr.Compile()).Select(b => new { b.F_Money, b.F_Name });
foreach (var item in _query)
{
Response.Write(item.F_Name + " " + item.F_Money.ToString() + "<br/>");
}
}
}
//得到合同金额大于6000,或合同名称中包含"江华"字的条件
private bool GetCondition(T_Bargin _Table)
{
bool _result = false;
decimal _MinMoney = 6000;
if (_MinMoney > 0)
{
_result |= _Table.F_Money >= _MinMoney;
}
string _Name = "江华";
if (!String.IsNullOrEmpty(_Name))
{
_result |= _Table.F_Name.Contains(_Name);
}
return _result;
}
借助老外写的一个扩展表达式的类,可以把上篇中的代码写得更优雅
这是PredicateBuilder的源文件
public static class PredicateBuilder
{
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>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.Or (expr1.Body, invokedExpr), expr1.Parameters);
}
public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.And (expr1.Body, invokedExpr), expr1.Parameters);
}
}
{
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>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.Or (expr1.Body, invokedExpr), expr1.Parameters);
}
public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.And (expr1.Body, invokedExpr), expr1.Parameters);
}
}
下面是使用示例 :
List<Product> GetProductsByAND(params string[] keywords)
{
DBDataContext db = new DBDataContext(Database.ConnectionString);
IQueryable<Product> query = db.Products;
foreach (string keyword in keywords)
{
string temp = keyword;
query = query.Where(p => p.Description.Contains(keyword));
}
//翻译后的sql语句:
//SELECT [t0].[ID], [t0].[Name], [t0].[Description]
//FROM [dbo].[Product] AS [t0]
//WHERE ([t0].[Description] LIKE '%手机%') AND ([t0].[Description] LIKE '%6111%')
return query.ToList();
}
List<Product> GetProductsByOR(params string[] keywords)
{
DBDataContext db = new DBDataContext(Database.ConnectionString);
var predicate = PredicateBuilder.False<Product>();
foreach (string keyword in keywords)
{
string temp = keyword;
predicate = predicate.Or(p => p.Description.Contains(temp));
}
var query = db.Products.Where(predicate);
//翻译后的sql语句:
//SELECT [t0].[ID], [t0].[Name], [t0].[Description]
//FROM [dbo].[Product] AS [t0]
//WHERE ([t0].[Description] LIKE '%6111%') OR ([t0].[Description] LIKE '%2350%')
return query.ToList();
}
void ShowData()
{
//var _products = GetProductsByOR("6111", "2350");
//Repeater1.DataSource = _products;
//Repeater1.DataBind();
var predicate = PredicateBuilder.True<Product>();
string _name = "6111";
if (!string.IsNullOrEmpty(_name))
{
predicate = predicate.And(p => p.Name.Contains(_name));
}
string _description = "长虹";
if (!string.IsNullOrEmpty(_description))
{
predicate = predicate.And(p => p.Description.Contains(_description));
}
using (DBDataContext db = new DBDataContext(Database.ConnectionString))
{
var _Products = db.Products.Where(predicate);
Repeater1.DataSource = _Products;
Repeater1.DataBind();
}
}
{
DBDataContext db = new DBDataContext(Database.ConnectionString);
IQueryable<Product> query = db.Products;
foreach (string keyword in keywords)
{
string temp = keyword;
query = query.Where(p => p.Description.Contains(keyword));
}
//翻译后的sql语句:
//SELECT [t0].[ID], [t0].[Name], [t0].[Description]
//FROM [dbo].[Product] AS [t0]
//WHERE ([t0].[Description] LIKE '%手机%') AND ([t0].[Description] LIKE '%6111%')
return query.ToList();
}
List<Product> GetProductsByOR(params string[] keywords)
{
DBDataContext db = new DBDataContext(Database.ConnectionString);
var predicate = PredicateBuilder.False<Product>();
foreach (string keyword in keywords)
{
string temp = keyword;
predicate = predicate.Or(p => p.Description.Contains(temp));
}
var query = db.Products.Where(predicate);
//翻译后的sql语句:
//SELECT [t0].[ID], [t0].[Name], [t0].[Description]
//FROM [dbo].[Product] AS [t0]
//WHERE ([t0].[Description] LIKE '%6111%') OR ([t0].[Description] LIKE '%2350%')
return query.ToList();
}
void ShowData()
{
//var _products = GetProductsByOR("6111", "2350");
//Repeater1.DataSource = _products;
//Repeater1.DataBind();
var predicate = PredicateBuilder.True<Product>();
string _name = "6111";
if (!string.IsNullOrEmpty(_name))
{
predicate = predicate.And(p => p.Name.Contains(_name));
}
string _description = "长虹";
if (!string.IsNullOrEmpty(_description))
{
predicate = predicate.And(p => p.Description.Contains(_description));
}
using (DBDataContext db = new DBDataContext(Database.ConnectionString))
{
var _Products = db.Products.Where(predicate);
Repeater1.DataSource = _Products;
Repeater1.DataBind();
}
}