动态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 ...
随机推荐
- scala 操作hdfs
获取hdfs文件下所有文件getAllFiles 遍历 spark读取 1 package com.spark.demo import java.io.IOException import java. ...
- ubunta apt install error
ubuntu系统: 用apt-get命令安装一些软件包时,总报错:E:could not get lock /var/lib/dpkg/lock -open等 出现这个问题的原因可能是有另外一个程序正 ...
- gradle 定义打包后的项目名
war { archiveName 'ROOT.war' } 或 task makeWar(type:org.gradle.api.tasks.bundling.War) { //指定生成的jar名 ...
- Java连接数据库 #02# JDBC经典套路
内容索引 LocalConnectionFactory.java LocalConnectionProxy.java ProfileDAO.java-2.0 ProfileDAOImpl.java-2 ...
- Spring Boot(八):RabbitMQ详解
Spring Boot(八):RabbitMQ详解 RabbitMQ 即一个消息队列,主要是用来实现应用程序的异步和解耦,同时也能起到消息缓冲,消息分发的作用. 消息中间件在互联网公司的使用中越来越多 ...
- atomic 原子操作
原子操作:操作仅由一个独立的CPU指令代表和完成.保证并发环境下原子操作的绝对安全 标准库代码包:sync/atomic atomic是最轻量级的锁,在一些场景下直接使用atomic包还是很有效的 C ...
- TNS-12537,TNS-12560,TNS-00507 Linux Error: 29: Illegal seek解决
下午有个测试环境测试人员反馈oracle监听起不来,一启动就报错,还生成了core文件.如下: [oracle@localhost ~]$ lsnrctl start LSNRCTL for Linu ...
- Python爬虫(一)——豆瓣下图书信息
爬虫目的: 随着近年互联网的发展,网络上的信息飞速数量增长.在庞大的数据面前想要获得期望的信息往往如同大海捞针.通过合理的筛选,在百万甚至数亿计的数据中找到所需信息,无疑有着非常大的意义. 在豆瓣网下 ...
- 2018年11月20日 远交近攻 list1
list 列表用法 li=[1,2,3,"abc"] #列表中的元素,可以为数字或者字符串或者布尔值或者就是列表等,所有都能放进去 #列表中也能嵌套列表 pi=[1,2,3,[2, ...
- uniGUI试用笔记(二)
前几天做的demo今天启动后,浏览器打开页面后死活不显示窗体,找了半天原因才发现是360浏览器启动了兼容模式,改成极速模式后就正常了.有点晕.... 今天简单测试了TUniGUIServerModul ...