18

是否有工具、过程或解决方案可以将以下 LINQ 查询语法转换为带有 Lambda 的方法语法(点表示法)?我希望解决方案将以下查询语法转换为这样的方法语法。

var filteredEmployees = 
    from employee in allEmployees
    where employee.DepartmentID < 4 && employee.EmployeeID < 10
    orderby employee.DepartmentID descending,
            employee.LastName descending
    select employee;

到以下

var filteredEmployees2 = allEmployees.Where(employee => ((employee.DepartmentID < 4) && (employee.EmployeeID < 10)))
        .OrderByDescending(employee => employee.DepartmentID)
        .ThenByDescending(employee => employee.LastName);

我想用它来更好地学习方法语法。

4

3 回答 3

24

LINQPad是满足您需要的好工具。我从他们的网站“偷”了以下屏幕截图,以更好地说明它是如何工作的。如果您使用 linq 语法编写查询,则可以单击以红色突出显示的按钮以查看等效的 lambda 语法:在此处输入图像描述

于 2013-03-03T21:47:41.833 回答
11

如果我们强制查询语法返回一个 IQueryable 类型,那么我们可以进入方法语法。

在这里,我将查询更改为返回 IQueryable 类型:

IQueryable<Employee> filteredEmployees = 
    (from employee in allEmployees.AsQueryable()
    where employee.DepartmentID < 4 && employee.EmployeeID < 10
    orderby employee.DepartmentID descending,
            employee.LastName descending
    select employee);

Console.WriteLine(filteredEmployees.ToString());

在前面的代码中,我们将“AsQueryable()”添加到“allEmployees”列表类型。返回类型现在将是 IQueryable,因此“filteredEmployees”现在将是“IQueryable”类型。然后在“filteredEmployees”上我们需要做的就是是调用“ToString()”方法。

以下内容被写入控制台。

System.Collections.Generic.List`1[UserQuery+Employee]
     .Where(employee => ((employee.DepartmentID < 4) AndAlso (employee.EmployeeID < 10)))
     .OrderByDescending(employee => employee.DepartmentID)
     .ThenByDescending(employee => employee.LastName)

它并不完美,但我们可以轻松地将其编辑为以下内容

IEnumerable<Employee> filteredEmployees2 = allEmployees
        .Where(employee => ((employee.DepartmentID < 4) && (employee.EmployeeID < 10)))
        .OrderByDescending(employee => employee.DepartmentID)
        .ThenByDescending(employee => employee.LastName);

Console.WriteLine(filteredEmployees);

在前面的代码中,我删除了“System.Collections.Generic.List`1[UserQuery+Employee]”并将其替换为“allEmployees”。我还将“AndAlso”替换为“&&”。

这将返回与查询语法中的查询相同的结果。

于 2013-03-03T02:52:17.450 回答
3

您可以通过声明生成一些对象的 lambda 表达式来获得更直接的表达式。实际的表达式将是您希望使用查询语法看到的查询。然后通过检查编译器生成的表达式树,您可以查看进行了哪些方法调用,而无需更改原始查询。

Expression<Func<object>> fn = () =>
    from employee in allEmployees
    where employee.DepartmentID < 4 && employee.EmployeeID < 10
    orderby employee.DepartmentID descending,
            employee.LastName descending
    select employee;
// inspect fn.Body

像您那样使用IQueryable<>不会生成相同的查询,但会稍作修改。AsQueryable()你必须忽略的电话。查询提供程序也有可能重写表达式,因此您使用的返回值ToString()可能没有 1:1 的对应关系。编译器生成的表达式正是您所期望的。

于 2013-03-03T03:47:27.277 回答