2012-12-21 46 views
1

我工作的項目,使用一些實體的動態linq查詢。 我有大量的案件,並避免代碼重複我重構到一種方法。 但是使用不在存儲表達式中的方法會導致拋出異常。 其中一個解決方案是將方法結果封裝到一個表達式中,該表達式可以被linq解釋爲實際查詢。linq實體和​​商店表達式

考慮一下代碼:

parentExpression = x => x.child.Any(y=>IsGoodChild(y,childType, childSize)); 

private bool IsGoodChild(child c, int childType, int childSize){ 
    return c.type == childType && c.size == childSize; 
} 

「parentExpression」 是我的EF型 「父母」 的斷言。 這段代碼拋出一個異常,「IsGoodChild」方法返回一個布爾值,不能被linq解釋爲實體。

所以,我想是這樣的:

parentExpression = x => x.child.AsQueryable().Any(IsGoodChild(childType, childSize)); 

private System.Linq.Expression.Expression<Func<child, bool>> IsGoodChild(int childType, int childSize){ 
    return ???? 
} 

所以,我該怎麼辦「IsGoodChild(...)」可以工作,即使它不採取x.child屬性? Thx的預先


RE,

我試一下,當我在表達直接寫入的λ是這樣的:

parentExpression = x => x.child.Any(y=>y.type == childType && y.size == childSize); 

i。從ReSharper的使用的提取物的方法,併產生它的:

private Expression<Func<child,Boolean>> IsGoodChildFunctional(Int32 childType, Int32 childSize) 
{ 
    return c => c.type == childType && c.size == childSize; 
} 

但我也有.NET框架數據提供程序rror 1025'錯誤...

回答

0

我找到了一個解決方案,所以我回答自己。

public static Expression<Func<TTargetObject,Boolean>> IsGoodChildFunctional<TTargetObject>(Int32 childType, Int32 childSize) 
{ 
      var e = Expression.Parameter(typeof(TTargetObject), "e"); 
      var childTypeMember = Expression.MakeMemberAccess(e, typeof(TTargetObject).GetProperty("childType")); 
      var childSizeMember = Expression.MakeMemberAccess(e, typeof(TTargetObject).GetProperty("childSize")); 
      var childTypeConstant = Expression.Constant(childType, childType.GetType()); 
      var childSizeConstant = Expression.Constant(childSize, childSize.GetType()); 
      BinaryExpression b; 
      BinaryExpression bBis; 
      Expression<Func<TTargetObject, bool>> returnedExpression; 
      b = Expression.Equal(childTypeMember , childTypeConstant); 
      bBis2 = Expression.Equal(childSizeMember, c2); 
      var resultExpression = Expression.AndAlso(b, bBis); 
      returnedExpression = Expression.Lambda<Func<TTargetObject, bool>>(resultExpression , e); 
      return returnedExpression; 
} 

這樣調用:

var predicat = IsGoodChildFunctional<child>(childType, childSize); 
parentExpression = x => x.child.Any(predicat); 

再見

0

在這種情況下,編譯器很聰明,給定一個匿名方法,它將根據聲明的類型在表達式樹或編譯的lambda之間切換。下面應該工作:

private Expression<Func<child,Boolean>> 
IsGoodChildFunctional(Int32 childType, Int32 childSize) 
{ 
    return c => c.type == childType && c.size == childSize; 
} 

這會像這樣使用:

parentExpression = x => x.child 
         .AsQueryable() 
         .Any(IsGoodChildFunctional(childType,childSize)); 
+0

只是學到了一些東西

我必須做一個靜態的通用方法,該方法將返回表達,表達通過工廠方法構建... –

+0

它不工作=> .NET Framework數據提供程序錯誤1025'錯誤 – bor1s

+1

它應該是'y => IsGoodChildFunctional(y.childType,y.childSize)'otherwis e lambda表達式仍然被視爲「Func」而不是表達式。另見http://stackoverflow.com/a/9517994/861716。 –