【问题标题】:linq to entities and store expressionlinq 到实体和存储表达式
【发布时间】:2018-08-15 22:37:17
【问题描述】:

我从事对实体使用一些动态 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' 错误...

【问题讨论】:

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


    【解决方案1】:

    在这种情况下,编译器很聪明,给定一个匿名方法,它会根据声明的类型在表达式树或编译的 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));
    

    【讨论】:

    • 它不起作用 => .NET Framework 数据提供程序错误 1025' 错误
    • 应该是 y =&gt; IsGoodChildFunctional(y.childType, y.childSize) 否则 lambda 表达式仍被视为 Func 而不是表达式。另请参阅stackoverflow.com/a/9517994/861716
    【解决方案2】:

    创建一个返回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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多