Linq-to-SQL, pass Expression <Func <T, T >> to select a method in the query syntax

Suppose we have the following code:

public class Dto { public int Id; public string Name; } ... using (var db = new NorthwindDataContext()) { var q = from boss in db.Employees from grunt in db.Employees.Where(p => p.ReportsTo == boss.EmployeeID).DefaultIfEmpty() select new Dto { Id = boss.EmployeeID, Name = grunt.FirstName }; } 

I want to extract the selector as an expression and save it elsewhere. In the method syntax, it will look like this:

 Expression<Func<Employee, Employee, Dto>> selector = (boss, grunt) => new Dto { Id = boss.EmployeeID, Name = grunt.FirstName }; using (var db = new NorthwindDataContext()) { var q = db.Employees.SelectMany(boss => db.Employees.Where(p => p.ReportsTo == boss.EmployeeID).DefaultIfEmpty(), selector); } 

Is it possible to convert this LinqToSql method chain into query syntax while keeping the Expression variable in place?

UPD:

To clarify my question, I am using DefaultIfEmpty for the left join, this is a short form of equal query:

 using (var db = new NorthwindDataContext()) { var q = from boss in db.Employees join stub in db.Employees on boss.EmployeeID equals stub.ReportsTo into stubi from grunt in stubi.DefaultIfEmpty() select new Dto { Id = boss.EmployeeID, Name = grunt.FirstName }; } 

which works fine because it compiles using the inline expression. It assigns null to the Name field if there is no corresponding grunt . But if you rewrite this request with a call to the mapper external method, it will be compiled by a method call that will receive a nullable grunt argument and will throw a NullReferenceException:

 public static Dto GetDto(Employee boss, Employee grunt) { return new Dto { Id = boss.EmployeeID, Name = grunt.FirstName }; } using (var db = new NorthwindDataContext()) { var q = from boss in db.Employees join stub in db.Employees on boss.EmployeeID equals stub.ReportsTo into stubi from grunt in stubi.DefaultIfEmpty() select GetDto(boss, grunt); } 

Of course, I can add null-check to the mapper method, but what I am trying to achieve in my DAL are selectors of selectors in the mapping classes and possibly omit null checks.

+4
source share
2 answers

I'm not sure why you need Expression - just use Func . This should work:

 Func<Employee, Employee, Dto> selector = (boss, grunt) => new Dto { Id = boss.EmployeeID, Name = grunt.FirstName }; using (var db = new NorthwindDataContext()) { var q = from boss in db.Employees from grunt in db.Employees.Where(p => p.ReportsTo == boss.EmployeeID).DefaultIfEmpty() select selector(boss, grunt) } 
0
source

You cannot always use query syntax; there are times when you can express calculations only using chains of methods. In this particular case, the query syntax introduces a lambda behind the scenes if the predicate was inline, but you put it in a variable, so you have no way to specify how to use this variable, like with a lambda supported by the query syntax.

0
source

Source: https://habr.com/ru/post/1441498/


All Articles