1

我从事对实体使用一些动态 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  ????
}

那么,即使不采用 x.child 属性,“IsGoodChild(...)”如何才能工作?谢谢提前


回覆,

我尝试了一些东西,当我直接在这样的表达式中编写 lambda 时:

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

我使用了 resharper 的提取方法并生成它:

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

但我也有 .NET Framework 数据提供程序错误 1025' 错误...

4

2 回答 2

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));
于 2012-12-21T13:34:20.120 回答
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);
于 2013-01-07T16:25:24.260 回答