Syntax for a method reference returning an expression to another method?

I found a code snippet of the following form:

public static Expression<Func<Invoice, CustomerContact>> GetCustomerContact() { return i => new CustomerContact { FirstName = i.Customer.FirstName, LastName = i.Customer.LastName, Email = i.Customer.Email, TelMobile = i.Customer.TelMobile, }; } 

In other parts of the code, I want to get the same easy CustomerContact object, not just from the invoice, but from the client itself. Therefore, it is obvious that you need to do the following:

 public static Expression<Func<Customer, CustomerContact>> GetCustomerContact() { return c => new CustomerContact { FirstName = c.FirstName, LastName = c.LastName, Email = c.Email, TelMobile = c.TelMobile, }; } 

and then change Expression to input Invoice to the input to access this method, i.e. something like this:

 public static Expression<Func<Invoice, CustomerContact>> GetCustomerContact() { return i => GetCustomerContact(i.Customer); // doesn't compile } 

What is the correct syntax for this?

+6
source share
2 answers

You can use Expression.Invoke :

 var paramExpr = Expression.Parameter(typeof(Invoice), "i"); var propertyEx = Expression.Property(paramExpr, "Customer"); var body = Expression.Invoke(GetCustomerContactFromCustomer(), propertyEx); return Expression.Lambda<Func<Invoice, CustomerContact>>(body, paramExpr); 

Note that some LINQ providers have problems with such call expressions.

The easiest way to get around this (and give you a more convenient syntax) is to use LINQKit :

 var expr = GetCustomerContactFromCustomer(); Expression<Func<Invoice, CustomerContact>> result = i => expr.Invoke(i.Customer); return result.Expand(); 
+3
source

Are you sure you need to use Expression ? If you don't need different Linq providers to convert code trees to queries, then consider Func instead. If you just use Func , the method signatures are as follows:

 public static Func<Customer, CustomerContact> GetCustomerContact(); 

and

 public static Func<Customer, CustomerContact> GetCustomerContact(); 

Then your syntax will be good for building a second Func from the first. Of course, this will only work for objects with memory (with Linq-to-objects).

The problem is that in order to build Expression it is necessary to explicitly build a rating tree, which can be quite hairy (using various static methods on Expression ). Because of this hairiness, there are several support packages, including LINQKit .

0
source

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


All Articles