经常使用从方法返回的LINQ

时间:2013-10-07 15:49:20

标签: c# linq

我有1个LINQ使用了这么多。我尝试创建返回此LINQ的方法,如:

    public static System.Linq.Expressions.Expression<Func<MyEntity, bool>> GetFilteredEntity() {
        return x => true/*Some condition*/;
    }

    public static Func<MyEntity, bool> GetFilteredEntity() {
        return x => true/*Some condition*/;
    }

并使用

    db.MyEntities.Where(GetFilteredEntity());

是成功的,但是!我需要像

一样使用它
    db.ParentEntities.Where(entity => entity.MyEntities.Where(GetFilteredEntity()));

这段代码也编译了,但每当我使用它时,我都会得到错误:

System.InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first.

,甚至:

db.ParentEntities.Where(entity => entity.MyEntities.Where(GetFilteredEntity())).ToList();

也抛出这个例外。

但是,

db.ParentEntities.Where(entity => entity.MyEntities.Where(x => true/*Some condition*/))

仍然可以正常工作! 那么为什么它会发生,并有一些方法来解决这个问题呢?

最终工作代码

public static Expression<Func<MyEntity, bool>> GetFilteredEntity() { return x => true/*Some condition*/; }

var expression = GetFilteredEntity();

db.ParentEntities.Where(entity => entity.MyEntities.AsQueryable().Where(expression ));

.AsQueryable()感谢Passing func as parameter in Linq to Entities and 'Internal .NET Framework Data Provider error 1025' error

2 个答案:

答案 0 :(得分:4)

在您的第一个示例中,函数被调用并在它甚至被发送到查询提供程序之前转换为表达式。在接下来的两个示例中,函数调用嵌入在发送给查询提供程序的表达式中,并且该查询提供程序不知道如何处理该函数调用,因此它只会抛出异常。当您将实际表达式嵌入另一个表达式时,没有函数调用来混淆查询提供程序。

至于解决方案,只需将函数调用拉入变量即可。查询提供程序 足够聪明,可以看到您使用了一个已关闭的over变量,并将提取其值。对于函数调用,它只是不确定它是否应该对它进行评估,或者尝试将其转换为应该在DB端完成的事情。对于查询提供者和使用它的人来说,尝试做两者中的某些操作会非常困惑并且难以使用。为了简化问题,在发送查询之前永远不会执行带表达式的函数调用。至于封闭的变量,没有其他方法可以对其进行处理,因此没有任何其他行为可以将其混淆。

var expression = GetFilteredEntity();
db.ParentEntities.Where(entity => entity.MyEntities.Where(expression ));

答案 1 :(得分:-1)

看起来LazyLoading可能是罪魁祸首,您是否尝试在参数上弹出ToList()?

db.ParentEntities.Where(entity => entity.MyEntities.Where(GetFilteredEntity()).ToList());