6

我找到了一段如下形式的代码:

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,
               };
}

在代码的其他部分,我想获得相同的轻量级CustomerContact对象,但不是来自 Invoice,而是来自 Customer 本身。所以显而易见的事情是:

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

然后ExpressionInvoice作为输入的输入更改为引用此方法,即如下所示:

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

什么是正确的语法?

4

2 回答 2

3

您可以使用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);

请注意,某些 LINQ 提供程序在此类调用表达式方面存在问题。

解决此问题的最简单方法(并为您提供更方便的语法)是使用LINQKit

var expr = GetCustomerContactFromCustomer();   
Expression<Func<Invoice, CustomerContact>> result = i => expr.Invoke(i.Customer);    
return result.Expand();
于 2013-06-02T09:09:50.107 回答
0

你确定你需要使用一个Expression?如果您不需要不同的 Linq 提供程序来将代码树转换为查询,那么请考虑改用 just Func。如果你只是使用Func这样的方法签名是:

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

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

那么你的语法可以很好地构建第一个的第二Func个。当然,这只适用于内存中的对象(使用 Linq-to-objects)。

问题在于,为了构建Expression,您必须显式地构建评估树,这可能非常麻烦(使用 上的各种静态方法Expression)。由于这种毛茸茸,有几个帮助程序包,包括LINQKit

于 2013-06-02T09:27:11.500 回答