拼接linq查询表达式        

1 比如在做数据库查询时面对前端可能多样的查询条件是,有时拼接查询条件能很方便的处理这种情况,如下代码所示

public GListResult<Entity.SysRole> GetList(Hashtable ht, int skip, int top)
{
System.Linq.Expressions.Expression<Func<Entity.SysRole, bool>> select = ff => ff.Id != 0;
System.Linq.Expressions.Expression<Func<Entity.SysRole, int>> orderBy = ob => ob.Id;
System.Linq.Expressions.Expression<Func<Entity.SysRole, bool>> subselect = ff => ff.Id == 0;
if (ht != null && ht.Count > 0)
{
if (ht.Contains("Id"))
{
select = select.And(ff => ff.Id == HQ.Job.Tools.StrHelper.ToInt32(ht["Id"].ToString()));
}
if (ht.Contains("RoleID"))
{
string[] arrRoleId = ht["RoleID"].ToString().Split(',');
foreach (string item in arrRoleId)
{
subselect=subselect.Or(ff => ff.Id == HQ.Job.Tools.StrHelper.ToInt32(item.ToString()));
}
select = select.And(subselect);
}
<pre name="code" class="csharp"><span style="white-space:pre"> </span>if (ht.Contains("Name"))
{
select = select.And(ff => ff.Name == HQ.Job.Tools.StrHelper.Format(ht["Name"].ToString()));
}

} var g = dal.GetAll(select, null, skip, top, orderBy); return g; }

dal.GetAll 的接口如下

GListResult<T> GetAll<TKey>(Expression<Func<T, bool>> query,
Expression<Func<T, T>> select, int skip, int top,
Expression<Func<T, TKey>> order = null, bool isDesOrder = false);


原生的linq暂还不支持select.And select.Or 这种写法,要借助这个扩展类LinqHelper,如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace HQ.Backstage.Business
{
public static class LinqHelper
{
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> one, Expression<Func<T, bool>> another)
{
var candidateExpr = Expression.Parameter(typeof(T), "candidate");
var parameterReplacer = new ParameterReplacer(candidateExpr);

var left = parameterReplacer.Replace(one.Body);
var right = parameterReplacer.Replace(another.Body);
var body = Expression.And(left, right);

return Expression.Lambda<Func<T, bool>>(body, candidateExpr);
}

public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> one, Expression<Func<T, bool>> another)
{
var candidateExpr = Expression.Parameter(typeof(T), "candidate");
var parameterReplacer = new ParameterReplacer(candidateExpr);

var left = parameterReplacer.Replace(one.Body);
var right = parameterReplacer.Replace(another.Body);
var body = Expression.Or(left, right);

return Expression.Lambda<Func<T, bool>>(body, candidateExpr);
}
internal class ParameterReplacer : ExpressionVisitor
{
public ParameterReplacer(ParameterExpression paramExpr)
{
this.ParameterExpression = paramExpr;
}

public ParameterExpression ParameterExpression { get; private set; }

public Expression Replace(Expression expr)
{
return this.Visit(expr);
}

protected override Expression VisitParameter(ParameterExpression p)
{
return this.ParameterExpression;
}
}
}
}


这样的话做查询处理就非常方便