How to Convert LINQ Comprehension Query Syntax to Method Syntax using Lambda

我们两清 提交于 2019-12-17 16:07:36

问题


Is there a tool, process or a solution that will convert the following LINQ Query Syntax to Method Syntax with Lambdas (dot notation)? I would expect the solution to convert the following Query Syntax to a Method Syntax such as this.

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

To the following

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

I'm would like to use this to learn Method Syntax better.


回答1:


LINQPad is a good tool for what you need. I "stole" the following screenshot from their website to better illustrate how it works. If you write a query using linq syntax you can click on the button highlighted in red to see the equivalent lambda syntax:




回答2:


If we force the Query Syntax to return a type of IQueryable then we can get to the Method Syntax.

Here I changed the query to return type of 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());

In the previous code we added "AsQueryable() to the "allEmployees" list type. The return type will now be IQueryable, so "filteredEmployees" will now be of type "IQueryable". Then on the "filteredEmployees" all we need to do is call "ToString()" method.

And the following is written to the console.

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

It's not perfect, but we can easily edit this to the following

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

Console.WriteLine(filteredEmployees);

In the previous code I removed "System.Collections.Generic.List`1[UserQuery+Employee]" and replaced it with "allEmployees". I also replace "AndAlso" with "&&".

This will return the same results as the query in the Query Syntax.




回答3:


You can get a more direct expression by declaring a lambda expression which generates some object. The actual expression will be the query you want to see using the query syntax. Then by inspecting the expression tree generated by the compiler, you can see what method calls are made without having to alter the original query.

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

Using IQueryable<> as you did there does not generate the same query but slightly modified. The AsQueryale() call you have to ignore. There's also the possibility that the query provider can rewrite the expression so what you get back using ToString() may not have a 1:1 correspondence. The compiler generated expression will be exactly what you would expect.



来源:https://stackoverflow.com/questions/15181933/how-to-convert-linq-comprehension-query-syntax-to-method-syntax-using-lambda

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!