在使用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动态查询的更多相关文章

  1. 动态创建Lambda表达式实现高级查询

    需求简介 最近这几天做的东西总算是回归咱的老本行了,给投资管理项目做一个台账的东西,就是类似我们的报表.其 中有一个功能是一个高级查询的需求,在查询条件方面大概有7.8个查询条件.需求就是如果一个条件 ...

  2. 动态创建 Lambda 表达式

    首先我们看一个简单 Lambda 表达式的构成. i => i > 5 在这个表达式中,"i" 被称为 Parameter,"i > 5" 是 ...

  3. easyui datagrid remoteSort的实现 Controllers编写动态的Lambda表达式 IQueryable OrderBy扩展

    EF 结合easy-ui datagrid 实现页面端排序 EF动态编写排序Lambda表达式 1.前端页面 var mainListHeight = $(window).height() - 20; ...

  4. 动态组合lambda 表达式

    //记录实体集合—动态组合lambda 表达式 Expression<Func<AdEntity, bool>> thirdWhere = p => p.Observer ...

  5. 【转】EntityFramework动态组合Lambda表达式作为数据筛选条件,代替拼接SQL语句

    传统的操作数据库方式,筛选数据需要用StringBuilder拼接一大堆的WHERE子句. 在Entity Framework中,代码稍有不慎就会造成巨大性能消耗,如: using(var db=ne ...

  6. [2014-12-30]如何动态构造Lambda表达式(动态构造Lambda查询条件表达式)

    声明 本文对Lambda表达式的扩展,示例代码来源于网络. 场景描述 web开发查询功能的时候,如果查询条件比较多,就会遇到动态组合查询条件的情况.在手写sql的情况下,我们一般会根据传入的参数,针对 ...

  7. 动态拼接lambda表达式树

    前言 最近在优化同事写的代码(我们的框架用的是dapperLambda),其中有一个这样很普通的场景——界面上提供了一些查询条件框供用户来进行过滤数据.由于dapperLambda按条件查询时是传入表 ...

  8. C#动态创建lambda表达式

    /// <summary> /// 创建lambda表达式:p=>true /// </summary> /// <typeparam name="T&q ...

  9. 使用Expression动态创建lambda表达式

    using System;using System.Linq.Expressions;using System.Reflection; namespace Helper{ public class L ...

随机推荐

  1. IT兄弟连 HTML5教程 CSS3属性特效 渐变1

    渐变背景一直以来在Web页面中都是一种常见的视觉元素.但一直以来,Web设计师都是通过图形软件设计这些渐变效果,然后以图片形式或者背景图片的形式运用到页面中.Web页面上实现的效果,仅从页面的视觉效果 ...

  2. 使用redisson时关于订阅数的问题

    在使用redisson消息订阅时,我针对门店商品库存减扣进行订阅的操作(在这里一个商品一个监听队列),当正式投入生产时,发现一直再报Subscribe timeout: (" + timeo ...

  3. WebShell代码分析溯源(四)

    WebShell代码分析溯源(四) 一.一句话变形马样本 <?php @$_++;$__=("`"^"?").(":"^"} ...

  4. ES6-WeakSet数组结构

    WeakSet 也会去重 总结: 1.成员都是对象: 2.成员都是弱引用,可以被垃圾回收机制回收,可以用来保存 DOM 节点,不容易造成内存泄漏: 3.不能遍历,方法有 add.delete.has. ...

  5. Node.js Error简介以及捕获方式

    error的类型nodejs 的error 一般分为四种类型: 1.标准的 JavaScript 错误,例如 EvalError.SyntaxError.RangeError.ReferenceErr ...

  6. Database mirroring connection error 4 'An error occurred while receiving data: '10054(An existing connection was forcibly closed by the remote host.)

    公司一SQL Server镜像发生了故障转移(主备切换),检查SQL Server镜像发生主备切换的原因,在错误日志中发现下面错误: Date        2019/8/31 14:09:17   ...

  7. MVC(实战一)

    一.创建MVC项目 二.界面分布 Content:是存放css文件等,暂时先不考虑. Controllers:重要, 控制层,控制界面显示和界面逻辑的,其实真正业务逻辑层,建议分层出去. Models ...

  8. JavaScript-----8.数组

    1.数组的概念 数组是指一组数据的集合,其中每个数据被称为元素,在数组中可以存放任意类型的元素 2. 创建数组 创建数组的两种方式: 利用new创建数组 利用数组字面量创建数组(最常用) 2.1 利用 ...

  9. Pro Micro

    选择这块Arduino板主要是因为它便宜(淘宝上20元左右搞定),引脚相对较多,体积小,而且其使用的处理器核心ATmega32U4(兼容Arduino Leonardo)可用于模拟HID设备,可以配合 ...

  10. 前端小白webpack学习(一)

    俗话说得好,好记性不如烂笔头. 之前就在学习中看过webpack的教程,然而一段时间没用,火速的忘光了.写这篇博文,做个总结,也让自己以后有个地方回顾. 看webpack之前,我先去看了一下官方文档, ...