6

I found a piece of code 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 lightweight CustomerContact object, only not from the Invoice, but from the Customer itself. So the obvious thing to do would be to have:

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 the Expression taking Invoice as input to refer to this method, i.e. something like this:

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

What's the correct syntax for this?

2
  • 2
    It'd be helpful if you posted the error. Commented Jun 2, 2013 at 9:03
  • @newStackExchangeInstance: "Method, delegate or event is expected" Commented Jun 2, 2013 at 9:10

2 Answers 2

3

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);

Do note that some LINQ providers have problems with such invocation-expressions.

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

var expr = GetCustomerContactFromCustomer();   
Expression<Func<Invoice, CustomerContact>> result = i => expr.Invoke(i.Customer);    
return result.Expand();
Sign up to request clarification or add additional context in comments.

3 Comments

Ouch, that's quite inelegant. Maybe that is the best solution, but I was hoping there would be a simpler solution that doesn't involve either reflection or third party extensions...
I don't think there's any way easier than Expression.Invoke to compose expressions in this manner. The LINQKIt way though is quite simple and elegant and gives you back the ability to use language lambdas for this.
Well, turns out LinqKit is going to be useful for my project in other areas. So thanks, and answer credit to you! :-)
0

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

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

and

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

Then your syntax would be fine for constructing the second Func off of the first one. Of course, this will only work for in-memory objects (with Linq-to-objects).

The problem is that in order to build an Expression, you have to explicitely build the evaluation tree, which can be quite hairy (using the various static methods on Expression). Because of this hairiness, there are several helper packages, including LINQKit.

2 Comments

Yeah, I do need an Expression; I want the query to run SQL-side.
Then go with Ani's solution!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.