首先感谢园子里的“红烧狮子头”,他的工作是本文的基础,引文如下http://www.cnblogs.com/daviddai/archive/2013/03/09/2952087.html,本版本实现了类似SQL中的like与in的功能,实现了多orderby的级联排序,下面贴出代码:

一些辅助类:

    public enum ConditionFlags
{
And = ,
Or = ,
} public enum RelationFlags
{
Equal = ,
NoEqual = ,
GreaterThan = ,
LessThan = ,
GreaterThanOrEqual = ,
LessThanOrEqual = ,
LikeWildcardBoth = ,
LikeLeftWildcardOnly = ,
LikeRightWildcardOnly = ,
In = ,
} public class QueryCondition
{
public string ConditionField { get; set; }
public object FieldValue { get; set; }
public ConditionFlags Condition { get; set; }
public RelationFlags Relation { get; set; }
} public class OrderByCondition
{
public string OrderField { get; set; }
public bool IsDesc { get; set; }
}

实现IEnumerable的实现方法:

        public static IEnumerable<T> GetDataByDynamicQuery<T>(this IEnumerable<T> sourceList, List<QueryCondition> queryConditionList, params OrderByCondition[] orderByConditionList)
{
if (null == sourceList)
{
throw new ArgumentException("source list must not be null");
} IQueryable<T> sourceLs = sourceList.AsQueryable(); Expression finalExpr;
Expression filter, totalExpr;
filter = totalExpr = Expression.Constant(true); ParameterExpression param = Expression.Parameter(typeof(T), "n");
foreach (var item in queryConditionList ?? Enumerable.Empty<QueryCondition>())
{
//反射找出所有查询条件的属性值,如果该查询条件值为空或者null不添加动态lambda表达式
string propertyName = item.ConditionField;
var propertyVal = item.FieldValue; if (!string.IsNullOrEmpty(propertyName) && propertyVal != null && propertyVal.ToString() != string.Empty)
{
//n.property
PropertyInfo property = typeof(T).GetProperty(propertyName);
Expression left = Expression.Property(param, property);
//等式右边的值
Expression right = Expression.Constant(propertyVal);
MethodInfo containsmethod;
switch (item.Relation)
{
case RelationFlags.Equal:
if (typeof(string) == property.PropertyType)
{
containsmethod = typeof(string).GetMethod("Equals", new[] { typeof(string), typeof(string), typeof(StringComparison) }); filter = Expression.Call(containsmethod,left, right, Expression.Constant(StringComparison.OrdinalIgnoreCase));
}
else
{
filter = Expression.Equal(left, right);
}
break;
case RelationFlags.NoEqual:
filter = Expression.NotEqual(left, right);
break;
case RelationFlags.GreaterThan:
filter = Expression.GreaterThan(left, right);
break;
case RelationFlags.LessThan:
filter = Expression.LessThan(left, right);
break;
case RelationFlags.GreaterThanOrEqual:
filter = Expression.GreaterThanOrEqual(left, right);
break;
case RelationFlags.LessThanOrEqual:
filter = Expression.LessThanOrEqual(left, right);
break;
case RelationFlags.LikeWildcardBoth:
if (typeof (string) == property.PropertyType)
{
containsmethod = property.PropertyType.GetMethod("Contains", new Type[] { property.PropertyType });
filter = Expression.Call(left, containsmethod, right);
}
else
{
throw new ArgumentException(" 'like %x%' operator work on string type only ");
}
break;
case RelationFlags.LikeLeftWildcardOnly:
if (typeof (string) == property.PropertyType)
{
containsmethod = property.PropertyType.GetMethod("EndsWith", new Type[] { property.PropertyType });
filter = Expression.Call(left, containsmethod, right);
}
else
{
throw new ArgumentException(" 'like %x' operator work on string type only ");
}
break;
case RelationFlags.LikeRightWildcardOnly:
if (typeof (string) == property.PropertyType)
{
containsmethod = property.PropertyType.GetMethod("StartsWith", new Type[] { property.PropertyType });
filter = Expression.Call(left, containsmethod, right);
}
else
{
throw new ArgumentException(" 'like x%' operator work on string type only ");
}
break;
case RelationFlags.In:
Expression rightTmp, filterTmp;
Expression totalExprTmp = Expression.Constant(false);
foreach (var itemValue in propertyVal as IEnumerable ?? Enumerable.Empty<object>())
{
rightTmp = Expression.Constant(itemValue);
if (typeof(string) == property.PropertyType)
{
containsmethod = typeof(string).GetMethod("Equals", new[] { typeof(string), typeof(string), typeof(StringComparison) });
filterTmp = Expression.Call(containsmethod,left, rightTmp, Expression.Constant(StringComparison.OrdinalIgnoreCase));
}
else
{
filterTmp = Expression.Equal(left, rightTmp);
}
totalExprTmp = Expression.Or(filterTmp, totalExprTmp);
}
filter = totalExprTmp = Expression.And(totalExprTmp, Expression.Constant(true));
break;
default:
filter = Expression.Constant(true);
break;
}
switch (item.Condition)
{
case ConditionFlags.And:
totalExpr = Expression.And(totalExpr, filter);
break;
case ConditionFlags.Or:
totalExpr = Expression.Or(totalExpr.NodeType.Equals(Expression.Constant(true).NodeType) ? Expression.Constant(false) : totalExpr, filter);
break;
default:
break;
}
}
}
//Where部分条件
Expression pred = Expression.Lambda(totalExpr, param);
finalExpr = Expression.Call(typeof(Queryable), "Where", new Type[] { typeof(T) }, Expression.Constant(sourceLs), pred);
string orderByFunctionName = "OrderBy";
string orderByDescFunctionName = "OrderByDescending";
foreach (var orderbyCondition in orderByConditionList ?? Enumerable.Empty<OrderByCondition>())
{
PropertyInfo pInfo = typeof(T).GetProperty(orderbyCondition.OrderField);
//OrderBy部分排序
finalExpr = Expression.Call(typeof(Queryable), orderbyCondition.IsDesc ? orderByDescFunctionName : orderByFunctionName, new Type[] { typeof(T), pInfo.PropertyType }, finalExpr, Expression.Lambda(Expression.Property(param, pInfo), param));
orderByFunctionName = "ThenBy";
orderByDescFunctionName = "ThenByDescending";
} return sourceLs.Provider.CreateQuery<T>(finalExpr);
}

调用示例:

            if (queryEntity.ApplicationIds != null && queryEntity.ApplicationIds.Length > )
{
var queryCondition = new QueryCondition
{
ConditionField = "ApplicationId",
FieldValue = queryEntity.ApplicationIds,
Condition = ConditionFlags.And,
Relation = RelationFlags.In
};
queryConditionList.Add(queryCondition);
}
if (!string.IsNullOrWhiteSpace(queryEntity.LinkPath))
{
var queryCondition = new QueryCondition();
queryCondition.ConditionField = "LinkPath";
queryCondition.FieldValue = queryEntity.LinkPath;
queryCondition.Condition = ConditionFlags.And;
queryCondition.Relation = RelationFlags.Equal;
queryConditionList.Add(queryCondition);
}
var orderByConditionList = new List<OrderByCondition>();
var orderByCondition = new OrderByCondition {OrderField = "SortIndex", IsDesc = true};
orderByConditionList.Add(orderByCondition);
var orderByConditionMenuId = new OrderByCondition {OrderField = "MenuId", IsDesc = false};
orderByConditionList.Add(orderByConditionMenuId);
return alllist.GetDataByDynamicQuery<ControlPanelMenuEntity>(queryConditionList, orderByConditionList.ToArray()).ToList();

动态LINQ构建(实现等于不等于大于小于,like以及IN)的更多相关文章

  1. 动态LINQ(Lambda表达式)构建

    using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; us ...

  2. 使用Expression Tree构建动态LINQ查询

    这篇文章介绍一个有意思的话题,也是经常被人问到的:如何构建动态LINQ查询?所谓动态,主要的意思在于查询的条件可以随机组合,动态添加,而不是固定的写法.这个在很多系统开发过程中是非常有用的. 我这里给 ...

  3. 自动化测试尝试 动态Linq表达式生成 ftp上传

    自动化测试尝试   1. Selenium IDE Selenium IDE is a Chrome and Firefox plugin which records and plays back u ...

  4. 基于领域驱动设计(DDD)超轻量级快速开发架构(二)动态linq查询的实现方式

    -之动态查询,查询逻辑封装复用 基于领域驱动设计(DDD)超轻量级快速开发架构详细介绍请看 https://www.cnblogs.com/neozhu/p/13174234.html 需求 配合Ea ...

  5. 动态Linq(结合反射)

    这篇文章决定对最近一个单机版Web程序用到的东西总结一下. 一.反射Linq之OrderBy 动态Linq结合反射对某字段排序: namespace 动态Linq { class Program { ...

  6. C# 动态Linq(结合反射)

      这篇文章决定对最近一个单机版Web程序用到的东西总结一下. 一.反射Linq之OrderBy 动态Linq结合反射对某字段排序: namespace 动态Linq { class Program ...

  7. Linq技术四:动态Linq技术 -- Linq.Expressions

    前面介绍了Linq的三个方面应用:Linq to SQL, Linq to XML和Linq to Object,这篇介绍一下动态Linq的实现方式及应用场景. 命名空间: System.Linq; ...

  8. Mybatis在xml配置文件中处理SQL中的大于小于号的方法

    之前在项目中遇到了在SQL中<=不识别的问题,在Navicat中语句正常,在xml中不识别,想起来就记录一下 项目用的是Mybatis,经过网上多次查询,验证,总结方法如下: 一.使用<! ...

  9. EF和linq语句查询条件不等于某个参数出现的问题

    where t.a!=字符串   这是错误的写法,正确为 where t.a!=字符串.trim() 其他类型变量需要保持实体类型和查询条件参数的类型是一致的,不然出现的语句可能会是 类似`Exten ...

随机推荐

  1. 魔方阵算法及C语言实现

    1 魔方阵概念 填充的,每一行.每一列.对角线之和均相等的方阵,阶数n = 3,4,5….魔方阵也称为幻方阵. 例如三阶魔方阵为: 魔方阵有什么的规律呢? 魔方阵分为奇幻方和偶幻方.而偶幻方又分为是4 ...

  2. Apache服务器中配置虚拟机的方法

    新浪微博虚拟机开发配置步骤及介绍.1.由于后面虚拟机中需要用到Rewrite所以先编辑Apache的conf目录下的httpd.conf文件.(可根据实际需要操作)添加mod_rewrite.so模块 ...

  3. Wince 中的图形编程

    图形编程程序当中,笔者主要要和大家讨论的是画刷的创建和使用以及绘图函数,比如2D图像的绘制等等. *画刷的定义: HBRUSH hBrush; *画刷的类型: 1. 系统内置画刷:GetStockOb ...

  4. java性能

    一.关于性能的基本知识  1.性能的定义  在我们讨论怎样提高Java的性能之前,我们需要明白“性能“的真正含义.我们一般定义如下五个方面作为评判性能的标准.  1) 运算的性能----哪一个算法的执 ...

  5. Spring(3.2.3) - Beans(11): depends-on

    大多数情况下,Bean 之间的依赖非常直接:被依赖的 Bean 作为属性.在 XML 配置文件中最常见的就是使用 <ref/> 元素.在一些特殊情况下,Bean 之间的依赖不够直接.比如, ...

  6. MyBatis(3.2.3) - Configuring MyBatis using XML, Properties

    The properties configuration element can be used to externalize the configuration values into a prop ...

  7. c#中网络异常的处理办法

    加入try catch来判断,catch使用的WebException来处理 try { var request = WebRequest.Create(uri); using (var respon ...

  8. HDOJ2008数值统计

    数值统计 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  9. 在Ubuntu中USB连接手机调试

    1.打开手机USB调试功能 显示“开发者选项”(开发者选项默认隐藏,一般需要进入到“设置”-->“关于手机”连续点击七次,可将“开发者选项显示出来”) 将“开发者选项”设置为“开启”状态 打开U ...

  10. AjaxPro使用方法

    无意中看到同事用AjaxPro用,看到很不错,特长是前后台传输数据特别方便. 最好的教材就是拿到就可以用,方便大家. 以前数据传输用FORM提交,或者在前台用JASON拼接然后通过AJAX方式提交.总 ...