动态LINQ(Lambda表达式)
1.准备数据实体
public class Data
{
public string AccountNO { get; set; } public int Count { get; set; }
}
创建测试数据
public static List<Data> GetTestData()
{
Data account = new Data
{
AccountNO = "",
Count =
}; Data account1 = new Data
{
AccountNO = "",
Count =
}; Data account2 = new Data
{
AccountNO = "",
Count =
}; Data account3 = new Data
{
AccountNO = "",
Count =
}; Data account4 = new Data
{
AccountNO = "",
Count =
};
var rel = new List<Data>
{
account,
account1,
account2,
account3,
account4
};
return rel;
}
2.准备查询条件实体
public class Condition
{
[DynamicExpression(Name = "AccountNO", Operator = "Contains")]
public string Name { get; set; } [DynamicExpression(Name = "Count", Operator = ">")]
public int? Age { get; set; }
}
数据实体2个字段一个帐号一个年龄大小
查询条件2个字段一个姓名(Name帐号)一个年龄(Age)
为了确保查询字段和数据字段名字保持一直 引用一个自定义特性 在查询条件的每个字段上面标记
自定义特性包含2个字段一个Name 需要跟数据实体保持一致的名称(注:必须和数据实体的字段对应) Operator 表示运算逻辑符
附自定义实体代码
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, AllowMultiple = true)]
public class DynamicExpressionAttribute : Attribute
{
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; } /// <summary>
/// 运行符号
/// </summary>
public string Operator { get; set; }
}
从查询条件中提取特效值的扩展类
public static class CustomAttributeExtension<TAttribute>
where TAttribute : Attribute
{
/// <summary>
/// Cache Data
/// </summary>
private static readonly Dictionary<string, TAttribute> Cache = new Dictionary<string, TAttribute>(); /// <summary>
/// 获取CustomAttribute Value
/// </summary>
/// <param name="type">实体对象类型</param>
/// <param name="propertyInfo">实体对象属性信息</param>
/// <returns>返回Attribute的值,没有则返回null</returns>
public static TAttribute GetCustomAttributeValue(Type type, PropertyInfo propertyInfo)
{
var key = BuildKey(type, propertyInfo);
if (!Cache.ContainsKey(key))
{
CacheAttributeValue(type, propertyInfo);
}
return Cache[key];
} /// <summary>
/// 获取CustomAttribute Value
/// </summary>
/// <param name="sourceType">实体对象数据类型</param>
/// <returns>返回Attribute的值,没有则返回null</returns>
public static TAttribute GetCustomAttributeValue(Type sourceType)
{
var key = BuildKey(sourceType, null);
if (!Cache.ContainsKey(key))
{
CacheAttributeValue(sourceType, null);
}
return Cache[key];
} /// <summary>
/// 获取实体类上的特性
/// </summary>
/// <param name="type">实体对象类型</param>
/// <returns>返回Attribute的值,没有则返回null</returns>
private static TAttribute GetClassAttributes(Type type)
{
var attribute = type.GetCustomAttributes(typeof(TAttribute), false).FirstOrDefault();
return (TAttribute)attribute;
} /// <summary>
/// 获取实体属性上的特性
/// </summary>
/// <param name="propertyInfo">属性信息</param>
/// <returns>返回Attribute的值,没有则返回null</returns>
private static TAttribute GetPropertyAttributes(PropertyInfo propertyInfo)
{
var attribute = propertyInfo?.GetCustomAttributes(typeof(TAttribute), false).FirstOrDefault();
return (TAttribute)attribute;
} /// <summary>
/// 缓存Attribute Value
/// <param name="type">实体对象类型</param>
/// <param name="propertyInfo">实体对象属性信息</param>
/// </summary>
private static void CacheAttributeValue(Type type, PropertyInfo propertyInfo)
{
var key = BuildKey(type, propertyInfo);
TAttribute value;
if (propertyInfo == null)
{
value = GetClassAttributes(type);
}
else
{
value = GetPropertyAttributes(propertyInfo);
} lock (key + "_attributeValueLockKey")
{
if (!Cache.ContainsKey(key))
{
Cache[key] = value;
}
}
} /// <summary>
/// 缓存Collection Name Key
/// <param name="type">type</param>
/// <param name="propertyInfo">propertyInfo</param>
/// </summary>
private static string BuildKey(Type type, PropertyInfo propertyInfo)
{
if (string.IsNullOrEmpty(propertyInfo?.Name))
{
return type.FullName;
}
return type.FullName + "." + propertyInfo.Name;
}
}
根据数据和查询条件生成表达式
public static Func<TResult, bool> GetDynamicExpression<TResult, TCondition>(this IEnumerable<TResult> data, TCondition condtion)
where TResult : class
where TCondition : class
{
Type tConditionType = typeof(TCondition);
Type tResultType = typeof(TResult); Expression totalExpr = Expression.Constant(true);
ParameterExpression param = Expression.Parameter(typeof(TResult), "n");
foreach (PropertyInfo property in tConditionType.GetProperties())
{
string key = property.Name;
object value = property.GetValue(condtion);
if (value != null && value.ToString() != string.Empty)
{
DynamicExpressionAttribute dynamicExpressionAttribute = CustomAttributeExtension<DynamicExpressionAttribute>.GetCustomAttributeValue(tConditionType, property); //等式左边的值
string name = dynamicExpressionAttribute.Name ?? key;
Expression left = Expression.Property(param, tResultType.GetProperty(name));
//等式右边的值
Expression right = Expression.Constant(value); Expression filter;
switch (dynamicExpressionAttribute.Operator)
{
case "!=":
filter = Expression.NotEqual(left, right);
break;
case ">":
filter = Expression.GreaterThan(left, right);
break;
case ">=":
filter = Expression.GreaterThanOrEqual(left, right);
break;
case "<":
filter = Expression.LessThan(left, right);
break;
case "<=":
filter = Expression.LessThanOrEqual(left, right);
break;
case "Contains":
filter = Expression.Call(Expression.Property(param, tResultType.GetProperty(name)), typeof(string).GetMethod("Contains", new [] { typeof(string) }), Expression.Constant(value)); ;
break;
default:
filter = Expression.Equal(left, right);
break;
}
totalExpr = Expression.And(filter, totalExpr);
}
}
var predicate = Expression.Lambda(totalExpr, param);
var dynamic = (Func<TResult, bool>)predicate.Compile();
return dynamic;
}
测试 : (查询帐号包含1的数据)
public static void Test()
{
var data = GetTestData();
var codition = new Condition { Name = "1"};
var dynamicExpression = GetDynamicExpression(data, codition);
var query1 = data.Where(dynamicExpression);
}
动态LINQ(Lambda表达式)的更多相关文章
- 【转】EntityFramework动态组合Lambda表达式作为数据筛选条件,代替拼接SQL语句
传统的操作数据库方式,筛选数据需要用StringBuilder拼接一大堆的WHERE子句. 在Entity Framework中,代码稍有不慎就会造成巨大性能消耗,如: using(var db=ne ...
- 动态创建Lambda表达式实现高级查询
需求简介 最近这几天做的东西总算是回归咱的老本行了,给投资管理项目做一个台账的东西,就是类似我们的报表.其 中有一个功能是一个高级查询的需求,在查询条件方面大概有7.8个查询条件.需求就是如果一个条件 ...
- 动态组合lambda 表达式
//记录实体集合—动态组合lambda 表达式 Expression<Func<AdEntity, bool>> thirdWhere = p => p.Observer ...
- easyui datagrid remoteSort的实现 Controllers编写动态的Lambda表达式 IQueryable OrderBy扩展
EF 结合easy-ui datagrid 实现页面端排序 EF动态编写排序Lambda表达式 1.前端页面 var mainListHeight = $(window).height() - 20; ...
- 动态构建Lambda表达式实现EF动态查询
在使用Entity Framework做数据查询的时候,查询条件往往不是固定的,需要动态查询.可以通过动态构建Lamda表达式来实现动态查询. Lamda表达式 使用Lamda表达式可以很方便的按条件 ...
- 动态创建 Lambda 表达式
首先我们看一个简单 Lambda 表达式的构成. i => i > 5 在这个表达式中,"i" 被称为 Parameter,"i > 5" 是 ...
- LinQ—Lambda表达式
概述 本篇博客主要解说lambda表达式,在这里将它的来龙去脉,主要是从托付,匿名函数这些方面过度讲的,当然,在讲托付和匿名函数的时候,主要是从Lambda的角度出发讲的,可能它们还具有其他的一些作用 ...
- 动态拼接lambda表达式树
前言 最近在优化同事写的代码(我们的框架用的是dapperLambda),其中有一个这样很普通的场景——界面上提供了一些查询条件框供用户来进行过滤数据.由于dapperLambda按条件查询时是传入表 ...
- [2014-12-30]如何动态构造Lambda表达式(动态构造Lambda查询条件表达式)
声明 本文对Lambda表达式的扩展,示例代码来源于网络. 场景描述 web开发查询功能的时候,如果查询条件比较多,就会遇到动态组合查询条件的情况.在手写sql的情况下,我们一般会根据传入的参数,针对 ...
- 使用Expression动态创建lambda表达式
using System;using System.Linq.Expressions;using System.Reflection; namespace Helper{ public class L ...
随机推荐
- jdbc连接 orale 和 mysql 所需要的jar包
oracle: ojdbc6-12.1.0.2.jar mysql: mysql-connector-java-5.1.47.jar
- 【javascript】对原型对象、原型链的理解
原型对象,原型链这些知识属于基础类知识.但是平时开发过程中也很少用到. 看网上的意思,原型链用于es5开发场景下的继承.es6有了类语法糖之后,就自带继承了. 通过理解,个人画了一张原型链解构的关系图 ...
- Java 判断字符串是否为空的四种方法、优缺点与注意事项
以下是Java 判断字符串是否为空的四种方法: 方法一: 最多人使用的一个方法, 直观, 方便, 但效率很低: if(s == null ||"".equals(s));方法二: ...
- PHP html mysql js 乱码问题,UTF-8(乱码)
一.HTML页面转UTF-8编码问题 1.在head后,title前加入一行: <meta http-equiv='Content-Type' content='text/html; chars ...
- 20165310 NstSec2019 Week3 Exp1 逆向与Bof基础
20165310 NstSec2019 Week3 Exp1 逆向与Bof基础 一.实验内容 实验目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用fo ...
- SSM集成activiti6.0错误集锦(一)
项目环境 Maven构建 数据库:Orcle12c 服务器:Tomcat9 <java.version>1.8</java.version> <activiti.vers ...
- 如何生成指定架构的Linux内核默认配置文件
答: make ARCH=<cpu architecture> defconfig 举例如下: make ARCH=arm64 defconfig (编译系统将会去目录arch/arm64 ...
- 集训总结DAY.1(18.5.22)——KMP
DAY 1——5.22 in the morning 依稀记得我们有一场contest. at night chf大佬讲KMP,先膜一波~~~ luoguP3375KMP模板题 KMP算法,又称模式匹 ...
- SpringBoot 全局统一记录日志
1.记录日志 使用aop来记录controller中的请求返回日志 pom.xml引入: <dependency> <groupId>org.springframework.b ...
- POJ 2226 Muddy Fields(最小点覆盖)题解
题意:一片r*c的地,有些地方是泥地,需要铺地板.这些地板宽1,长无限,但只能铺在泥地上不能压到其他地方,问你铺满所有泥地最少几块 思路:我们把一行中连续的泥地看成整体,并把所有横的整体里的点编成一个 ...