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