[英]How to chain FilterDefinitionBuilders in Mongo.Net Driver
I have a filter that I would like to add to each of my queries as a basis to any of my queries that I am going to perform on the database. 我有一个过滤器,我想将其添加到每个查询中,作为我将要在数据库上执行的任何查询的基础。 This will mean that i don't have to remember to add a filter ( filter.Eq("deleted", false) & filter.Eq("another query", null)
on every call i make to my collection. 这意味着我不必记住在我对集合的每次调用中都添加一个过滤器( filter.Eq("deleted", false) & filter.Eq("another query", null)
。
Using other fluent interfaces in the past i assumed that we could simply pass the builder around adding as many filters as i liked until I was actually ready to perform the query and then i would call a .Build()
command and this would finally give me my FilterDefinition
object. 过去使用其他流利的接口,我假设我们可以简单地通过构建器来添加我喜欢的过滤器,直到我准备好执行查询为止,然后我将调用.Build()
命令,这最终将给我我的FilterDefinition
对象。
However when I try combining the Eq()
calls it simply converts to a FilterDefinition
straight away rather than leaving it as a FilterDefinitionBuilder
until it's time has come. 但是,当我尝试组合Eq()
调用时,它只是立即转换为FilterDefinition
,而不是直到需要时才将其保留为FilterDefinitionBuilder
。 This seems fairly inextensible and short sighted by the Mongo as adding a .Build()
functionality would have allowed you to chain commands in a more flexible manner. 这似乎是Mongo不可.Build()
和短视的,因为添加.Build()
功能可以使您以更灵活的方式链接命令。
Firstly is there any reason behind the decision to do it in this manner. 首先,以这种方式做出决定的背后有任何理由。 I want to understand why it was done like this as I know that people don't just arbitrarily make these decisions. 我想了解为什么这样做是因为我知道人们不会随便做出这些决定。
Secondly, has anyone managed to write any extension methods that would help me with my current predicament that they wouldn't mind sharing. 其次,有没有人设法编写任何扩展方法来帮助我解决当前他们不介意共享的困境。
My first attempt was to include something like the following: 我的第一个尝试是包含以下内容:
public static FilterDefinitionBuilder<TDocument>(this FilterDefinitionBuilder<TDocument> filter)
{
var name = GetCollectionName<TDocument>();
return filter.Eq("deleted", false);
}
Then i would call this to from a wrapper function that I would use instead of calling the static Builders<CosmosDocumentType>.Filter
I would call a utility function that would wrap this and return a FilterDefinitionBuilder
object that I can add some more filters to. 然后,我将从包装函数调用此函数,而不是调用静态Builders<CosmosDocumentType>.Filter
我将调用一个实用程序函数,将其包装并返回一个FilterDefinitionBuilder
对象,可以向其中添加更多过滤器。
Once complete I'd like to call a .Build()
method and then be presented with a rather lovely and rather functional FilterDefinition
object that will get what documents I want from the collection. 完成后,我想调用.Build()
方法,然后为它提供一个相当可爱且功能强大的FilterDefinition
对象,该对象将从集合中获取我想要的文档。
Having this .Build()
would also allow me to query all documents in a collection that are not deleted without having to add more filters, because at present this seems to be the only way to convert between a FilterDefinitionBuilder
and a FilterDefinition
. 拥有这个.Build()
还将使我能够查询集合中所有未删除的文档而不必添加更多过滤器,因为当前这似乎是在FilterDefinitionBuilder
和FilterDefinition
之间进行转换的唯一方法。
The other alternative is writing my own Fluent wrapper around the functionality and run it through a FilterDefinitionBuilder
at the end when I am satisfied that I have all of the filters in place. 另一种选择是围绕功能编写我自己的Fluent包装器,并在我对所有过滤器都安装到位感到满意时,最后通过FilterDefinitionBuilder
运行它。
If there is a way to pull the existing filters out of a FilterDefinition
that might also help. 如果有一种方法可以将现有过滤器从FilterDefinition
中拉出,则可能也有帮助。
As I understand it, you need to decorate all your filters with a base filter . 据我了解,您需要使用基本过滤器装饰所有过滤器 。 You can carry out using various approaches and I list three below. 您可以使用多种方法进行操作,下面列出了三种方法。
Let's say you have the following for your base filter: 假设您的基本过滤条件如下:
var builder = Builders<BsonDocument>.Filter;
var baseFilter = builder.Eq("deleted", false) &
builder.Eq("another query", BsonNull.Value);
And the following filters that you need to decorate: 以及您需要装饰的以下过滤器:
var filter01 = Builders<BsonDocument>.Filter.Eq("value", 1);
var filter02 = Builders<BsonDocument>.Filter.Eq("value", 2);
Then: 然后:
Its implementation is simple as follows: 它的实现很简单,如下所示:
public static Func<FilterDefinition<T>, FilterDefinition<T>>
DecoratedFilter<T>(FilterDefinition<T> baseFilter) =>
filter => baseFilter & filter;
You can now use the DecoratedFilter()
function to get a function and use it on your filters as follows: 现在,您可以使用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;
It can be used as follows: 可以如下使用:
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;
Then simply use it as: 然后只需将其用作:
var decoratedFilter01 = filter01.WithBaseFilter();
var decoratedFilter02 = filter02.WithBaseFilter();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.