C#中Lambda表达式类型Expression不接受lambda函数
在EF Core中我们经常会用System.Linq.Expressions系统命名空间的Expression<TDelegate>类型来作为EF Core的查询条件,比如:
using EFLambdaExpression.Entities;
using System;
using System.Linq;
using System.Linq.Expressions; namespace EFLambdaExpression
{
class Program
{
static void Main(string[] args)
{
using (FinanceDigitalToolContext dbContext = new FinanceDigitalToolContext())
{
Expression<Func<User, bool>> userExperssion = u => u.UserCode != null; var users = dbContext.User.Where(userExperssion).ToList();
} Console.WriteLine("Press key to quit...."); Console.ReadLine();
}
}
}
但是如果我们将Expression<Func<User, bool>> userExperssion = u => u.UserCode != null改为Expression<Func<User, bool>> userExperssion = u => { return u.UserCode != null; }那么C#会报错,提示:
A lambda expression with a statement body cannot be converted to an expression tree
所以Expression<Func<User, bool>> userExperssion不能接受带函数体的u => { return u.UserCode != null; }这种lambda函数,它只支持简单的lambda表达式u => u.UserCode != null
虽然Expression<Func<User, bool>> userExperssion右边的lambda表达式中可以使用自定义函数,但是不建议这么做,因为这么做会导致EF Core对数据库表做全表查询
比如我们先执行下面的代码:
using EFLambdaExpression.Entities;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Linq.Expressions; namespace EFLambdaExpression
{
class Program
{
static void Main(string[] args)
{
using (FinanceDigitalToolContext dbContext = new FinanceDigitalToolContext())
{
Expression<Func<User, bool>> userExperssion = u => EF.Functions.Like(u.UserCode, "%ADMIN%"); var users = dbContext.User.Where(userExperssion).ToList();
} Console.WriteLine("Press key to quit...."); Console.ReadLine();
}
}
}
可以从EF Core的日志中看到生成了如下SQL语句:
=============================== EF Core log started ===============================
Executed DbCommand (122ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [u].[ID], [u].[CompanyCode], [u].[CreateTime], [u].[DataStatus], [u].[FirstName], [u].[LastName], [u].[MailAddress], [u].[MiddleName], [u].[Password], [u].[UserCode], [u].[Username]
FROM [MD].[User] AS [u]
WHERE [u].[UserCode] LIKE N'%ADMIN%'
=============================== EF Core log finished ===============================
因为EF.Functions.Like方法是EF Core定义的系统函数,所以我们看到EF Core可以将该C#方法转换为SQL查询中的LIKE语句作为查询的WHERE条件。
如果现在我们将EF.Functions.Like的调用放到我们自定义的一个C#方法UserCodeLike中去,然后在Expression<Func<User, bool>> userExperssion右边的lambda表达式中调用自定义方法UserCodeLike,代码如下所示:
using EFLambdaExpression.Entities;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Linq.Expressions; namespace EFLambdaExpression
{
class Program
{
static bool UserCodeLike(User user, string pattern)
{
return EF.Functions.Like(user.UserCode, pattern);
} static void Main(string[] args)
{
using (FinanceDigitalToolContext dbContext = new FinanceDigitalToolContext())
{
Expression<Func<User, bool>> userExperssion = u => UserCodeLike(u, "%ADMIN%"); var users = dbContext.User.Where(userExperssion).ToList();
} Console.WriteLine("Press key to quit...."); Console.ReadLine();
}
}
}
可以从EF Core的日志中看到生成了如下SQL语句:
=============================== EF Core log started ===============================
Executed DbCommand (124ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [u].[ID], [u].[CompanyCode], [u].[CreateTime], [u].[DataStatus], [u].[FirstName], [u].[LastName], [u].[MailAddress], [u].[MiddleName], [u].[Password], [u].[UserCode], [u].[Username]
FROM [MD].[User] AS [u]
=============================== EF Core log finished ===============================
可以看到,虽然最后查出来的结果是一样的,但是这次EF Core对User表做了全表查询,在SQL的查询语句中没有生成任何WHERE条件,说明EF Core不认识我们定义的UserCodeLike方法,不知道怎么将UserCodeLike方法转换为对应的SQL语句,所以干脆就做了全表查询,将User表的数据从数据库全查出来后,再调用我们的UserCodeLike方法来过滤数据,如果User表的数据量非常大,这样效率其实会非常低。所有不建议在EF Core的lambda表达式中使用自定义函数。
C#中Lambda表达式类型Expression不接受lambda函数的更多相关文章
- 委托、匿名委托、Lambda 表达式、Expression表达式树之刨根问底
本篇不是对标题所述之概念的入门文章,重点在阐述它们的异同点和应用场景.各位看官,这里就不啰嗦了,直接上代码. 首先定义一个泛型委托类型,如下: public delegate T Function&l ...
- C# Lambda表达式详解,及Lambda表达式树的创建
最近由于项目需要,刚刚学完了Action委托和Func<T>委托,发现学完了委托就必须学习lambda表达式,委托和Lambda表达式联合起来,才能充分的体现委托的便利.才能使代码更加简介 ...
- 死磕Lambda表达式(二):Lambda的使用
城市就是森林,每一个男人都是猎手,每一个女人都是陷阱.--<三体> 在哪使用Lambda表达式? 在上一篇文章(传送门)中介绍了Lambda表达式的基本语法,其中的举了一个Lambda表达 ...
- 获取lambda表达式类型,获取attributes是注意事项
1.获取lambda表达式的MemberExpression所属类的类型,要使用:m.Expression.Type 而不要使用 m.Member.DeclaringType: 后者获取的是实际定 ...
- Lambda表达式 和 Expression<T>
经常用的Lambda表达式 返回的是 Expression<T> 格式 public class ActivityService { private readonly List<A ...
- C++中的动态类型与动态绑定、虚函数、运行时多态的实现
动态类型与静态类型 静态类型 是指不需要考虑表达式的执行期语义,仅分析程序文本而决定的表达式类型.静态类型仅依赖于包含表达式的程序文本的形式,而在程序运行时不会改变.通俗的讲,就是上下文无关,在编译时 ...
- mysql中的timestamp类型时间比较:unix_timestamp函数
在mysql中,某字段的类型设置为了timestamp,那么我们现在希望取出指定时间段的记录,该如何做呢? 在php中有time()和strtotime()来进行日期和时间戳的格式化,而在mysql中 ...
- 深入学习C#匿名函数、委托、Lambda表达式、表达式树类型——Expression tree types
匿名函数 匿名函数(Anonymous Function)是表示“内联”方法定义的表达式.匿名函数本身及其内部没有值或者类型,但是可以转换为兼容的委托或者表达式树类型(了解详情).匿名函数转换的计算取 ...
- .NET中那些所谓的新语法之三:系统预定义委托与Lambda表达式
开篇:在上一篇中,我们了解了匿名类.匿名方法与扩展方法等所谓的新语法,这一篇我们继续征程,看看系统预定义委托(Action/Func/Predicate)和超爱的Lambda表达式.为了方便码农们,. ...
随机推荐
- Alice's Print Service
Alice's Print Service Time Limit: 2 Seconds Memory Limit: 65536 KB Alice is providing print ser ...
- ExceptionHelper异常工具类
using System;using System.Collections.Generic;using System.Text; namespace JiaWel.Utilities{ public ...
- html和css入门 (四)
背景样式 背景颜色 属性名 background-color 属性值 合法的颜色的名,比如:red:十六进制值,比如:#ff0000:RGB 值,比如:rgb(255,0,0) 默认值 transpa ...
- ccf-201609-2 火车购票
问题描述 请实现一个铁路购票系统的简单座位分配算法,来处理一节车厢的座位分配. 假设一节车厢有20排.每一排5个座位.为方便起见,我们用1到100来给所有的座位编号,第一排是1到5号,第二排是6到10 ...
- CSS animation online生成工具
利用HTML5.css的一些动画功能,可以设计出非常炫酷的动画,但是由于并不是所有的浏览器都支持,所以可能需要prefix,这个过程是比较烦的.一个比较好用的线上工具: http://matthewl ...
- Linux ->> UBuntu 14.04 LTE下安装Hadoop 1.2.1(伪分布模式)
Hadoop的运行模式可分为单机模式.伪分布模式和分布模式. 首先无论哪种模式都需要安装JDK的,这一步之前的随笔Ubuntu 14.04 LTE下安装JDK 1.8中已经做了.这里就不多说了. 其次 ...
- js 获取URL中参数
function getQueryString() { var result = location.search.match(new RegExp("[\?\&][^\?\& ...
- window 服务注册、卸载
1.以管理员身份打开 命令窗口 2.服务注册命令:sc create myServer binpath= path 3.服务卸载命令:sc delete myServer Topshelf 服务安装 ...
- QT的QPropertyAnimation讲解
m_pAnimation->setEasingCurve(QEasingCurve::Linear); //直线风格 m_pAnimation->setLoopCount(-1); //无 ...
- yii2.0里自己写的源码上传图片
在做项目过程中,用了源码表单上传, <form action="?r=pre/create" method="post" enctype="mu ...