问题
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