linq到实体和商店表达

时间:2012-12-21 09:48:05

标签: c# linq linq-to-entities linq-expressions predicatebuilder

我处理的项目使用一些动态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'错误...

2 个答案:

答案 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)

创建一个静态泛型方法,该方法将返回ExpressionExpression是使用工厂方法构建的。

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);