2011-05-02 54 views
1

我正尝试在实体框架查询中使用表达式。 我创建了两个表达式:结合了两个表达式

public Expression<Func<IEntityPriceDefinition, bool>> IsMatchExpression(long additionId) 
    { 
     return x => x.PriceDefinition.AdditionsPrices.Any(a => a.AdditionId == additionId); 
    } 
public Expression<Func<IEntityPriceDefinition, bool>> IsMatchExpression(
    long? inviterId, long? routeId, long? luggageTypeId) 
{ 
    return x => 
     (inviterId.HasValue || routeId.HasValue || luggageTypeId.HasValue) && 
     !(
      (x.PriceDefinition.InviterId.HasValue && inviterId.HasValue && 
       PriceDefinition.InviterId.Value != inviterId.Value) || 

      (PriceDefinition.LuggageTypeId.HasValue && luggageTypeId.HasValue && 
       PriceDefinition.LuggageTypeId.Value != luggageTypeId.Value) || 

      (PriceDefinition.InviterId.HasValue && inviterId.HasValue && 
       PriceDefinition.InviterId.Value != inviterId.Value) 
     ); 
} 

现在我愿意将它们合并:

public Expression<Func<IEntityPriceDefinition, bool>> IsMatchExpression(
     long? inviterId, long? routeId, long? luggageTypeId, long additionId) 
    { 
     return IsMatchExpression(inviterId, routeId, luggageTypeId) && 
       IsMatchExpression(additionId); 
    } 

此方法不编译。我也有这种感觉,我做错了什么。我该如何解决它?

编辑:
我忘了重要的一部分!该问题已更新。

+2

应返回布尔值,否? – Nicolas78 2011-05-02 09:56:34

+0

@ Nicolas78:我需要创建将结合两个表达式的表达式。 – Naor 2011-05-02 10:06:20

+0

啊好的。以及你在这里写的评估两个表达式,并尝试返回true或false取决于是否都符合。也许你可以对这些MatchExpressions和你的用例做一些说明,这样我们可以更好地帮助你。 – Nicolas78 2011-05-02 10:12:46

回答

0

刚刚创建的组合方法:

public Expression<Func<IEntityPriceDefinition, bool>> IsMatchExpression(
     long? inviterId, long? routeId, long? luggageTypeId, long additionId) 
    { 
    return x => 
     (inviterId.HasValue || routeId.HasValue || luggageTypeId.HasValue) && 
     (x.PriceDefinition.AdditionsPrices.Any(a => a.AdditionId == additionId)) && 
     !(
      (x.PriceDefinition.InviterId.HasValue && inviterId.HasValue && 
       PriceDefinition.InviterId.Value != inviterId.Value) || 

      (PriceDefinition.LuggageTypeId.HasValue && luggageTypeId.HasValue && 
       PriceDefinition.LuggageTypeId.Value != luggageTypeId.Value) || 

      (PriceDefinition.InviterId.HasValue && inviterId.HasValue && 
       PriceDefinition.InviterId.Value != inviterId.Value) 
     ); 
} 

不是最好的解决方案,但它的工作原理。

0

确定不可能是某事像

var x = IsMatchExpression(inviterId, routeId, luggageTypeId) 
var y = IsMatchExpression(additionId); 
return arg => x(arg) && y(arg) 

+0

您可能需要一些额外的语法巫毒,我不熟悉Expression接口;但是关键是在函数中调用这些函数与返回一个lambda函数之间的区别,该函数将在 – Nicolas78 2011-05-02 10:22:37

+0

后面调用返回值,但这不起作用。我相信我使用错误的表达式界面。我不确定这是为实体框架查询创建表达式的方式。 – Naor 2011-05-02 10:32:57

+0

究竟“不工作”是什么意思? (错误信息等)? – Nicolas78 2011-05-02 10:38:54

1

您必须直接使用表达式组件来完成此操作。

public Expression<Func<IEntityPriceDefinition, bool>> IsMatchExpression(
     long? inviterId, long? routeId, long? luggageTypeId, long additionId) 
{ 
    var a = IsMatchExpression(inviterId, routeId, luggageTypeId); 
    var b = IsMatchExpression(additionId); 
    var p = Expression.Parameter(typeof(IEntityPriceDefinition),"x"); 
    var c = Expression.AndAlso(Expression.Invoke(a,p),Expression.Invoke(b,p)); 
    var r = Expression.Lambda<Func<IEntityPriceDefinition, bool>>(c,p); 
    return r; 
} 

这可以通过从每两个表达式的爆发的.Body和更换(使用ExpressionVisitor)的与所述新的参数的参数进行更复杂的;并且您的两个工作方法中的每一个都可以更改为将它们的参数绑定到ConstantExpression s,完全丢失了lambda表达式语法。实际上,这些更改可能对于使用实体框架能够正常工作的表达式是必要的,但是这需要一些时间才能解决问题。

另请参见How can I compose an Entity Framework query from smaller, resusable queries?

+0

它创建了一个异常:'System.Func'2 [IEntityPriceDefinition,System.Boolean]'类型的表达式不能用于返回类型'System.Boolean'。 – Naor 2011-05-04 10:57:46

+0

哪一行有错误? – Random832 2011-05-04 11:41:16

+0

它试图从它制作lambda的地方:var r = Expression.Lambda >(c,p); – Naor 2011-05-04 11:46:52