1

例如,在 MongoDb 中,我可以将谓词传递给可查询的实例

DataBase.GetCollection<BsonDocument>("entity")
    .AsQueryable<Entity>()
    .Where(item=>item.id ==5);

但现在我有这样的功能

IEnumerbale QueryData(Predicate<Entity> condition)
{
    this.DataBase.GetCollection<BsonDocument>("entity")
        .AsQueryable<Entity>()
        .Where(item=> condition(item));
}

但这不起作用并告诉我:

不支持的 where 子句:。

这是设计好的吗?有什么解决方法吗?难道我做错了什么?

4

3 回答 3

4

你甚至没有传递一个表达式。您的条件对 MongoDB 来说是一个完全不透明的函数。

您需要传入一个Expression<Func<Entity,bool>>并调用 Where 像这样:

Where(condition)
于 2012-06-13T18:38:03.830 回答
2

Where 子句必须转换为发送到服务器的 MongoDB 查询。当您像这样传入任意 Predicate 时,LINQ 层不知道将其翻译成什么。所以不能支持那种类型的开放式 Where 子句。

于 2012-06-13T18:17:54.210 回答
0

传递 Lambda 表达式作为参数来过滤来自 mongodb 集合的数据。您的数据过滤功能可能是

public IEnumerable<BsonDocument> FindAllWithPredicate(Func<BsonDocument, bool> condition)
{
    return Collection.AsQueryable().Where(condition).ToArray();
}

谓词生成器.cs

public static class PredicateBuilder
{
    public static Expression<Func<T, bool>> True<T>()
    {
        return f => true;
    }

    public static Expression<Func<T, bool>> False<T>()
    {
        return f => false;
    }

    public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1,
        Expression<Func<T, bool>> expr2)
    {
        var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
        return Expression.Lambda<Func<T, bool>>
            (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);
    }

    public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1,
        Expression<Func<T, bool>> expr2)
    {
        var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
        return Expression.Lambda<Func<T, bool>>
            (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);
    }
}   

通过谓词生成器生成 lambda 表达式

public static class PredicateBuilderStore
{
    public static Func<BsonDocument, bool> GetPredicateForBsonDocument(Entity entity)
    {
        var predicate = PredicateBuilder.True<BsonDocument>();            
        predicate = predicate.And(d => d.GetElement({key}).Value == CompareWithValue);
        return predicate.Compile();
    }   
}

如果您只想查询所有项目,您可以这样做:

return this.collection.Find(_=>true).ToArray();
于 2018-07-27T17:27:22.007 回答