2012-12-21 45 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。 –