C#中Lambda表达式类型Expression不接受lambda函数
在EF Core中我們經(jīng)常會用System.Linq.Expressions系統(tǒng)命名空間的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#會報(bào)錯,提示:
A lambda expression with a statement body cannot be converted to an expression tree所以Expression<Func<User, bool>> userExperssion不能接受帶函數(shù)體的u => { return u.UserCode != null; }這種lambda函數(shù),它只支持簡單的lambda表達(dá)式u => u.UserCode != null
?
雖然Expression<Func<User, bool>> userExperssion右邊的lambda表達(dá)式中可以使用自定義函數(shù),但是不建議這么做,因?yàn)檫@么做會導(dǎo)致EF Core對數(shù)據(jù)庫表做全表查詢
比如我們先執(zhí)行下面的代碼:
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 ===============================因?yàn)镋F.Functions.Like方法是EF Core定義的系統(tǒng)函數(shù),所以我們看到EF Core可以將該C#方法轉(zhuǎn)換為SQL查詢中的LIKE語句作為查詢的WHERE條件。
?
如果現(xiàn)在我們將EF.Functions.Like的調(diào)用放到我們自定義的一個C#方法UserCodeLike中去,然后在Expression<Func<User, bool>> userExperssion右邊的lambda表達(dá)式中調(diào)用自定義方法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 ===============================可以看到,雖然最后查出來的結(jié)果是一樣的,但是這次EF Core對User表做了全表查詢,在SQL的查詢語句中沒有生成任何WHERE條件,說明EF Core不認(rèn)識我們定義的UserCodeLike方法,不知道怎么將UserCodeLike方法轉(zhuǎn)換為對應(yīng)的SQL語句,所以干脆就做了全表查詢,將User表的數(shù)據(jù)從數(shù)據(jù)庫全查出來后,再調(diào)用我們的UserCodeLike方法來過濾數(shù)據(jù),如果User表的數(shù)據(jù)量非常大,這樣效率其實(shí)會非常低。所有不建議在EF Core的lambda表達(dá)式中使用自定義函數(shù)。
?
總結(jié)
以上是生活随笔為你收集整理的C#中Lambda表达式类型Expression不接受lambda函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 洛谷P4114 Qtree1(树链剖分+
- 下一篇: 微软向Linux社区开放60000多项专