我有一个过滤器,我想将其添加到每个查询中,作为我将要在数据库上执行的任何查询的基础。这意味着我不必记住要在我对收藏集的每次调用中添加过滤器(filter.Eq("deleted", false) & filter.Eq("another query", null)
。
过去我使用其他流利的接口,我想我们可以简单地通过构建器来添加我喜欢的任意数量的过滤器,直到我准备好执行查询为止,然后我将调用.Build()
命令,最终会给我我的FilterDefinition
对象。
但是,当我尝试合并Eq()
调用时,它只是立即转换为FilterDefinition
,而不是将其保留为FilterDefinitionBuilder
直到时间到了。这似乎是Mongo不可扩展和短视的,因为添加.Build()
功能可以使您以更灵活的方式链接命令。
首先,以这种方式做出决定的背后没有任何理由。我想了解为什么这样做是因为我知道人们不会随便做出这些决定。
第二,有没有人设法编写任何扩展方法,这些扩展方法可以帮助我解决当前他们不介意共享的困境。
我的第一个尝试是包含以下内容:
public static FilterDefinitionBuilder<TDocument>(this FilterDefinitionBuilder<TDocument> filter)
{
var name = GetCollectionName<TDocument>();
return filter.Eq("deleted", false);
}
然后,我将从包装函数调用此函数,而不是调用静态Builders<CosmosDocumentType>.Filter
,而是调用实用程序函数将其包装并返回一个我可以添加的FilterDefinitionBuilder
对象一些更多的过滤器。
完成后,我想调用.Build()
方法,然后看到一个相当可爱且功能强大的FilterDefinition
对象,该对象将从集合中获取我想要的文档。
拥有此.Build()
还将使我能够查询集合中所有未删除的文档而不必添加更多过滤器,因为目前看来,这是在{{1}之间进行转换的唯一方法}和FilterDefinitionBuilder
。
另一种选择是围绕功能编写我自己的Fluent包装器,并在我对所有过滤器都安装到位感到满意后,通过FilterDefinition
运行它。
如果有一种方法可以将现有过滤器从FilterDefinitionBuilder
中拉出来,这也可能会有所帮助。
答案 0 :(得分:2)
据我了解,您需要使用基本过滤器 装饰所有过滤器。您可以使用多种方法进行操作,我在下面列出了三种方法。
假设您的基本过滤条件如下:
var builder = Builders<BsonDocument>.Filter;
var baseFilter = builder.Eq("deleted", false) &
builder.Eq("another query", BsonNull.Value);
以及需要装饰的以下过滤器:
var filter01 = Builders<BsonDocument>.Filter.Eq("value", 1);
var filter02 = Builders<BsonDocument>.Filter.Eq("value", 2);
然后:
它的实现很简单,如下所示:
public static Func<FilterDefinition<T>, FilterDefinition<T>>
DecoratedFilter<T>(FilterDefinition<T> baseFilter) =>
filter => baseFilter & filter;
您现在可以使用DecoratedFilter()
函数来获取一个函数,并按如下所示在过滤器上使用它:
var decorate = DecoratedFilter(baseFilter);
var decoratedFilter01 = decorate(filter01);
var decoratedFilter02 = decorate(filter02);
public static FilterDefinition<T>
Decorate<T>(this FilterDefinition<T> firstFilter,
FilterDefinition<T> secondFilter) =>
firstFilter & secondFilter;
它可以如下使用:
var decoratedFilter01 = filter01.Decorate(baseFilter);
var decoratedFilter02 = filter02.Decorate(baseFilter);
public static readonly FilterDefinition<BsonDocument> BaseFilter = ...
public static FilterDefinition<BsonDocument>
WithBaseFilter(this FilterDefinition<BsonDocument> filter) =>
BaseFilter & filter;
然后只需将其用作:
var decoratedFilter01 = filter01.WithBaseFilter();
var decoratedFilter02 = filter02.WithBaseFilter();