Entity Framework 和扩展方法中的委托

Entity Framework and delegates in extension methods

最近我在使用 EF 的 LINQ 扩展中使用委托作为谓词时遇到了问题。 这是一个简单的例子。

Func<LmsIdentityUser, bool> predicate = u => u.FullName.Contains(val) || u.EmployeeId.Contains(val);
var result = _ctx.Users.Where(predicate).ToList();
var result2 = _ctx.Users.Where(u => u.FullName.Contains(val) || u.EmployeeId.Contains(val)).ToList();

我预计这两个查询应该产生相同的 SQL 查询,因为 Where() 中使用的谓词是相同的。唯一的区别是,在第一种情况下,它是使用委托定义的。 但这里是 EF 针对这些情况生成的实际 SQL 查询。

案例一(使用委托)

SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[EmployeeId] AS [EmployeeId], 
[Extent1].[FullName] AS [FullName]    
FROM [dbo].[AspNetUsers] AS [Extent1]

案例二(直接使用lambda)

SELECT TOP (15) 
[Extent1].[Id] AS [Id], 
[Extent1].[EmployeeId] AS [EmployeeId], 
[Extent1].[FullName] AS [FullName]
FROM [dbo].[AspNetUsers] AS [Extent1]
WHERE ([Extent1].[FullName] LIKE @p__linq__0 ESCAPE N'~') OR ([Extent1].[EmployeeId] LIKE @p__linq__1 ESCAPE N'~')

所以问题是委托有什么问题?我应该怎么做才能在 LINQ 扩展中使用它们?

委托的形式为 Func<Input, Output>,而 LINQ 查询的形式为 Expression<Func<Input, Output>>。 LINQ 解析表达式以生成查询,而委托对 SELECT 查询返回的数据进行操作。请注意,委托版本根本没有过滤。

我相信您可以将谓词更改为 Expression<Func<>> 以获得您正在寻找的行为。