我可以将谓词传递给可查询的实例,例如
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子句:。
这是按照设计的吗? 有没有解决方法?我做错了吗?
答案 0 :(得分:4)
你甚至没有传递表达方式。您的条件对MongoDB来说是一个完全不透明的函数。
你需要传递一个Expression<Func<Entity,bool>>
并调用这样的地方:
Where(condition)
答案 1 :(得分:2)
必须将Where子句转换为发送到服务器的MongoDB查询。当你传递任意谓词时,LINQ层不知道要将它翻译成什么。因此,不支持这种开放式Where子句。
答案 2 :(得分:0)
传递Lambda表达式作为参数,以过滤mongodb集合中的数据。 您的数据过滤器功能可能是
public IEnumerable<BsonDocument> FindAllWithPredicate(Func<BsonDocument, bool> condition)
{
return Collection.AsQueryable().Where(condition).ToArray();
}
Predicatebuilder.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();