动态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 ...
随机推荐
- Makefile依赖关系中的竖线“|”
网上搜索无果,于是自己查看了一下makefile的info文件,其中解释如下: [java] view plain copy print? target : prerequisites [TAB] ...
- golang中tcp socket粘包问题和处理
转自:http://www.01happy.com/golang-tcp-socket-adhere/ 在用golang开发人工客服系统的时候碰到了粘包问题,那么什么是粘包呢?例如我们和客户端约定数据 ...
- 20145320《网络对抗》注入Shellcode并执行
20145320注入Shellcode并执行 准备一段Shellcode 首先先准备一段C语言代码:这段代码其实和我们的shell功能基本一样 为了之后能够看到反汇编的结果,这次采用的静态编译.正常返 ...
- innerHTML和 innerText的区别
共同点:innerHTML和innerText都会把元素内内容替换掉.不同点:1,innerHTML: 也就是从对象的起始位置到终止位置的全部内容,包括Html标签. 上例中的test.innerHT ...
- git 如何revert指定范围内的commit并且只生成一个新的commit?
答:一共分成两步 一. revert多个commit并生成多个新的commit git revert <old commit>^..<new commit> 二. 使用reba ...
- 日志统计 尺取法【蓝桥杯2018 C/C++ B组】
标题:日志统计 小明维护着一个程序员论坛.现在他收集了一份"点赞"日志,日志共有N行.其中每一行的格式是: ts id 表示在ts时刻编号id的帖子收到一个"赞" ...
- JXOI2018守卫 区间DP
链接 https://loj.ac/problem/2545 思路 f[i][j]表示i到j区间的最小监视人数 可以预处理出来g[i][j],表示i能否监视到j (其实预处理的关系不大,完全可以直接判 ...
- vs2015 + Python3.5 环境搭建
1. vs2015只支持Python3.5及以前的版本,对应Anaconda3.4.2之前的版本. 2. 卸载掉所有安装过的Python 3. 建议重装VS2015, 因为增量升级Python Too ...
- IQR(Inter-Quartile Range)
IQR(Inter-Quartile Range)在统计中叫内距.内距又称为四分位差.具体如下:内距IQR即Inter-Quartile Range, 这是统计技术上的名词.内距又称为四分位差,是两个 ...
- LuoguP2680 运输计划
题目地址 题目链接 题解 二分答案,那么大于答案的路径都需要有一条公共边,maxlen-val>=二分出来的x.val是边权. 考虑树剖,对每条大于答案的路径都+1(线段树里),枚举边,如果(线 ...