我处理的项目使用一些动态linq查询到实体。 我有大量的案例,并避免代码重复我重构一个方法。 但是使用不在store表达式中的方法将导致抛出异常。 解决方案之一是将方法结果封装到一个表达式中,该表达式可以由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类型“Parent”的谓词。 此代码抛出异常,“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 for advance
RE,
当我在表达式中直接写lambda时,我尝试了一些东西:
parentExpression = x => x.child.Any(y=>y.type == childType && y.size == childSize);
我使用resharper中的extract方法生成它:
private Expression<Func<child,Boolean>> IsGoodChildFunctional(Int32 childType, Int32 childSize)
{
return c => c.type == childType && c.size == childSize;
}
但我也有.NET Framework数据提供程序错误1025'错误...
答案 0 :(得分: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));
答案 1 :(得分:0)
创建一个静态泛型方法,该方法将返回Expression
。 Expression
是使用工厂方法构建的。
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);