动态构建Lambda表达式实现EF动态查询
在使用Entity Framework做数据查询的时候,查询条件往往不是固定的,需要动态查询。可以通过动态构建Lamda表达式来实现动态查询。
Lamda表达式
使用Lamda表达式可以很方便的按条件过滤数据。Entity Framework也是将Lamda表达式转换成对应的SQL语句执行。
比如下列代码,输出年龄大于1的人的名字:
namespace ConsoleApp
{
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
class MyDbContext : DbContext
{
public DbSet<Person> People { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=(local);Database=TestDB;User Id=sa;Password=sa;");
}
} class Program
{
static void Main(string[] args)
{
MyDbContext dbContext = new MyDbContext(); foreach (var item in dbContext.People.Where(m => m.Age > ))
{
Console.WriteLine(item.Name);
}
}
}
}
peoples.Where(m => m.Age > 1)这个在代码里面写死了,如果要换条件就一定要改代码。
Expression
先看一下Where里面是什么,Where里面是表达式的主体,分为参数m,左边参数m的属性和右边的值,通过中间的大于运算符进行比较运算。所以我们在构建表达式的时候,也需要构建这四个部分:
- 参数
- 参数的属性
- 值
- 运算符
参数
参数有类型和名字:
Type type= typeof(Person);
var parameter = Expression.Parameter(type, "m");
属性
我们需要知道属性的名称和类型,可通过反射来得到对应的类型并和刚刚的参数关联起来:
PropertyInfo property = type.GetProperty("Age");
Expression expProperty = Expression.Property(parameter, property.Name);
值
我们还需构建一个值的表达式:
Expression<Func<object>> valueLamda = () => ;
Expression expValue = Expression.Convert(valueLamda.Body, property.PropertyType);
因为值委托的返回类型是object,所以需要使用Expression.Convert来转换成正确的类型。
如果值是简单类型,如int, string等,也可以直接使用Expression.Constant,简单一些:
Expression expValue = Expression.Constant();
运算符
现在已经有了属性表达式,值表达式,接下来就是要使用运算符表达式把它们连接起来:
Expression expression = Expression.GreaterThan(expProperty, expValue);
将表达式转换成对应的类型即可以使用了:
Expression<Func<Person, bool>> filter = ((Expression<Func<Person, bool>>)Expression.Lambda(expression, parameter));
foreach (var item in dbContext.People.Where(filter))
{
Console.WriteLine(item.Name);
}
下面是完整代码
namespace ConsoleApp
{
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
class MyDbContext : DbContext
{
public DbSet<Person> People { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=(local);Database=TestDB;User Id=sa;Password=sa;");
}
} class Program
{
static void Main(string[] args)
{
MyDbContext dbContext = new MyDbContext(); Type type = typeof(Person);
var parameter = Expression.Parameter(type, "m"); PropertyInfo property = type.GetProperty("Age");
Expression expProperty = Expression.Property(parameter, property.Name); Expression<Func<object>> valueLamda = () => ;
Expression expValue = Expression.Convert(valueLamda.Body, property.PropertyType); Expression expression = Expression.GreaterThan(expProperty, expValue);
Expression<Func<Person, bool>> filter = ((Expression<Func<Person, bool>>)Expression.Lambda(expression, parameter));
foreach (var item in dbContext.People.Where(filter))
{
Console.WriteLine(item.Name);
}
}
}
}
这样就可以通过动态传入属性名和值来进行动态查询了。
封装和使用
我们做了一些简单的封装,更方便使用,代码:
https://github.com/SeriaWei/ZKEACMS/blob/master/src/EasyFrameWork/LINQ/Query.cs
使用QueryCollection来添加条件,最后转成表达式:
static void Main(string[] args)
{
MyDbContext dbContext = new MyDbContext(); QueryCollection queries = new QueryCollection();
queries.Add(new Query { Name = "Age", Operator = Query.Operators.GreaterThan, Value = }); foreach (var item in dbContext.People.Where(queries.AsExpression<Person>()))
{
Console.WriteLine(item.Name);
}
}
原文地址:http://www.zkea.net/codesnippet/detail/entity-framework-dynamic-search.html
动态构建Lambda表达式实现EF动态查询的更多相关文章
- 动态创建Lambda表达式实现高级查询
需求简介 最近这几天做的东西总算是回归咱的老本行了,给投资管理项目做一个台账的东西,就是类似我们的报表.其 中有一个功能是一个高级查询的需求,在查询条件方面大概有7.8个查询条件.需求就是如果一个条件 ...
- 动态创建 Lambda 表达式
首先我们看一个简单 Lambda 表达式的构成. i => i > 5 在这个表达式中,"i" 被称为 Parameter,"i > 5" 是 ...
- easyui datagrid remoteSort的实现 Controllers编写动态的Lambda表达式 IQueryable OrderBy扩展
EF 结合easy-ui datagrid 实现页面端排序 EF动态编写排序Lambda表达式 1.前端页面 var mainListHeight = $(window).height() - 20; ...
- 动态组合lambda 表达式
//记录实体集合—动态组合lambda 表达式 Expression<Func<AdEntity, bool>> thirdWhere = p => p.Observer ...
- 【转】EntityFramework动态组合Lambda表达式作为数据筛选条件,代替拼接SQL语句
传统的操作数据库方式,筛选数据需要用StringBuilder拼接一大堆的WHERE子句. 在Entity Framework中,代码稍有不慎就会造成巨大性能消耗,如: using(var db=ne ...
- [2014-12-30]如何动态构造Lambda表达式(动态构造Lambda查询条件表达式)
声明 本文对Lambda表达式的扩展,示例代码来源于网络. 场景描述 web开发查询功能的时候,如果查询条件比较多,就会遇到动态组合查询条件的情况.在手写sql的情况下,我们一般会根据传入的参数,针对 ...
- 动态拼接lambda表达式树
前言 最近在优化同事写的代码(我们的框架用的是dapperLambda),其中有一个这样很普通的场景——界面上提供了一些查询条件框供用户来进行过滤数据.由于dapperLambda按条件查询时是传入表 ...
- C#动态创建lambda表达式
/// <summary> /// 创建lambda表达式:p=>true /// </summary> /// <typeparam name="T&q ...
- 使用Expression动态创建lambda表达式
using System;using System.Linq.Expressions;using System.Reflection; namespace Helper{ public class L ...
随机推荐
- sed 使用正则表达式进行替换
echo "111(222)333" | sed 's/(\(.*\))\(.*\)/\2\2\2/' \1 \2 表示匹配的第几个() 在进行模式匹配时,() 需要加转义符号\ ...
- threejs 绘制辅助网格
GridHelper.js可以帮助绘制一个xz平面网格,它没有提供更多的参数,所以不能用于生成xy网格. xy网格实现代码如下: var size = 6000; var divisions = 50 ...
- python 打飞机项目 (实战一)
第一步定义 main 函数: # -*- coding=utf-8 -*- import pygame,time from Plane import Plane from pygame.locals ...
- 在Ubuntu 18.04系统上安装Pydio Cells详细图文教程
前言 基于云的协作工具Pydio cell提供了一系列灵活的特性,包括应用内消息传递.文件共享和版本控制.下面逐步介绍安装过程. Pydio cell最初是一个简单的基于云的文件共享系统,但经过升 ...
- 实战Netty集群
疯狂创客圈 Java 分布式聊天室[ 亿级流量]实战系列之 -25[ 博客园 总入口 ] 1.写在前面 1.1 实战Netty集群的理由 Java基础练习中,一个重要的实战练习是: java的聊天程序 ...
- 推荐一种非常好的新版DSP库源码移植方式,含V7,V6和V5的IAR以及MDK5的AC5和AC6版本
说明: 1.新版CMSIS V5.6里面的DSP库比以前的版本人性化了好多. 2.本帖为大家分享一种源码的添加方式,之前一直是用的库方便,不方便查看源码部分. 3.DSP教程可以还看第1版的,在我们的 ...
- 对《Java核心技术卷一》读者的一些建议
<Java核心技术卷一>是唯一可以和<Java编程思想>媲美的一本 Java 入门书.单从技术的角度来看,前者更好一些.但上升到思想层面嘛,自然后者更好,两者的偏重点不同. 思 ...
- Exceptionless应用--自定义插件
遇到的问题/需求 这里会把一些敏感的参数记录下来,我们需要屏蔽掉,如图 我们希望日志里面有当前登录用户的信息,如图: 处理方法 tip:这里用的是.net非.net core 第一个问题(屏蔽敏感参数 ...
- C# -- 模拟扑克牌发牌
C# -- 模拟扑克牌发牌 1. User 类: 玩家 public class User { private List<PaperCard> listCard = new List&l ...
- DispatchProxy实现动态代理及AOP
DispatchProxy类是DotnetCore下的动态代理的类,源码地址:Github,官方文档:MSDN.主要是Activator以及AssemblyBuilder来实现的(请看源码分析),园子 ...