2011-05-02 86 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