动态LINQ构建(实现等于不等于大于小于,like以及IN)
首先感谢园子里的“红烧狮子头”,他的工作是本文的基础,引文如下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)的更多相关文章
- 动态LINQ(Lambda表达式)构建
using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; us ...
- 使用Expression Tree构建动态LINQ查询
这篇文章介绍一个有意思的话题,也是经常被人问到的:如何构建动态LINQ查询?所谓动态,主要的意思在于查询的条件可以随机组合,动态添加,而不是固定的写法.这个在很多系统开发过程中是非常有用的. 我这里给 ...
- 自动化测试尝试 动态Linq表达式生成 ftp上传
自动化测试尝试 1. Selenium IDE Selenium IDE is a Chrome and Firefox plugin which records and plays back u ...
- 基于领域驱动设计(DDD)超轻量级快速开发架构(二)动态linq查询的实现方式
-之动态查询,查询逻辑封装复用 基于领域驱动设计(DDD)超轻量级快速开发架构详细介绍请看 https://www.cnblogs.com/neozhu/p/13174234.html 需求 配合Ea ...
- 动态Linq(结合反射)
这篇文章决定对最近一个单机版Web程序用到的东西总结一下. 一.反射Linq之OrderBy 动态Linq结合反射对某字段排序: namespace 动态Linq { class Program { ...
- C# 动态Linq(结合反射)
这篇文章决定对最近一个单机版Web程序用到的东西总结一下. 一.反射Linq之OrderBy 动态Linq结合反射对某字段排序: namespace 动态Linq { class Program ...
- Linq技术四:动态Linq技术 -- Linq.Expressions
前面介绍了Linq的三个方面应用:Linq to SQL, Linq to XML和Linq to Object,这篇介绍一下动态Linq的实现方式及应用场景. 命名空间: System.Linq; ...
- Mybatis在xml配置文件中处理SQL中的大于小于号的方法
之前在项目中遇到了在SQL中<=不识别的问题,在Navicat中语句正常,在xml中不识别,想起来就记录一下 项目用的是Mybatis,经过网上多次查询,验证,总结方法如下: 一.使用<! ...
- EF和linq语句查询条件不等于某个参数出现的问题
where t.a!=字符串 这是错误的写法,正确为 where t.a!=字符串.trim() 其他类型变量需要保持实体类型和查询条件参数的类型是一致的,不然出现的语句可能会是 类似`Exten ...
随机推荐
- SQL Server2008附加数据库失败
今天旁晚时分,我准备把老师在上课时候发给我们的一个数据库附加到我的SQL Server2008上面去,本来在学校机房用的SQL Server2000是很顺利地就成功了,但是把*.mdf文件附加到我的0 ...
- javaweb学习总结六(泛型)
一:泛型的概念 泛型用来现在集合中的存储类型,防止取出时强制转换发生错误. 1:没有使用泛型时,如下: @Test public void test1() { List list = new Arra ...
- Ajax返回xml类型数据
ajax可以返回文本类型数据和xml类型数据,xml是计算机通用语言 可以使用js解析返回xml类型数据的dom对象 前端页面 <!doctype html> <html lang= ...
- hide(1000)跟show(1000)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Lombok(1.14.8) - @NoArgsConstructor, @RequiredArgsConstructor & @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor,提供一个无参的构造方法. package com.huey.hello.bean; import java.util.Dat ...
- Lombok(1.14.8) - @NonNull
@NonNull @NonNull,生成一个非空检查. package com.huey.lombok; import lombok.Getter; import lombok.NonNull; im ...
- 参数请求post, get , delete中的基本使用(1)
/// <summary> /// get 数据的时候可以采用此函数大部分功能 /// </summary> /// <param name="args&quo ...
- android 中int 和 String 互相转换的多种方法
1 .如何将字串 String 转换成整数 int? A. 有两个方法: 1). int i = Integer.parseInt([String]); 或 i = Integer.parseInt( ...
- 转摘 Eclipse智能提示及快捷键
1.java智能提示 (1). 打开Eclipse,选择打开" Window - Preferences". (2). 在目录树上选择"Java-Editor-Conte ...
- dreamweaver中用正则表达式查找替换批量删除 tppabs标签的方法
查找替换 正则表达式 \btppabs="h[^"]*" 后面不能有空格 你懂得的 选中右下角的 √[使用正则表达式] 替换全部