在EF Core中咱们常常会用System.Linq.Expressions系统命名空间的Expression<TDelegate>类型来做为EF Core的查询条件,好比:git
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 != nullexpress
虽然Expression<Func<User, bool>> userExperssion右边的lambda表达式中可使用自定义函数,可是不建议这么作,由于这么作会致使EF Core对数据库表作全表查询函数
好比咱们先执行下面的代码:ui
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语句:spa
=============================== 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,代码以下所示:code
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语句:blog
=============================== 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表达式中使用自定义函数。string