C# 中 MongoDB 的直通投影定义
Pass-through projection definition for MongoDB in C#
我有一个函数,用于通过 Mongo 数据库中的 ID 检索对象,它看起来像这样:
public async Task<IEnumerable<TItem>> GetItemsAsync(uint limit,
Expression<Func<TItem, bool>> filter = null,
SortDefinition<TItem> sort = null,
ProjectionDefinition<TItem> projection = default,
CancellationToken token = default) {
// First, create the options describing which objects will be returned
var findOptions = new FindOptions<TItem> {
Limit = (int)limit,
Sort = sort,
Projection = projection
};
// Next, connect to the specific collection in the database
IMongoCollection<TItem> collection = GetCollection();
// Now, attempt to find all the items associated with the filter and find options
IAsyncCursor<TItem> cursor = await collection.FindAsync(filter ?? FilterDefinition<TItem>.Empty,
findOptions, token).ConfigureAwait(false);
// Finally, retrieve all the items and return them
return await cursor.ToListAsync(token).ConfigureAwait(false);
}
我遇到的问题是,在我想要 return 文档中的所有字段因此不提供投影的情况下,这会中断。在这种情况下,我得到以下异常:
System.ArgumentNullException: Value cannot be null. (Parameter 'projection')
at MongoDB.Driver.Core.Misc.Ensure.IsNotNull[T](T value, String paramName)
at MongoDB.Driver.KnownResultTypeProjectionDefinitionAdapter`2..ctor(ProjectionDefinition`1 projection, IBsonSerializer`1 projectionSerializer)
at MongoDB.Driver.ProjectionDefinition`2.op_Implicit(ProjectionDefinition`1 projection)
我的问题是:是否有传递投影定义或以编程方式将从 MongoDB 文档检索到的所有字段映射到我的 return 对象的方法?
感谢@Llama 的建议,我得以解决此问题。我将代码重构为如下所示:
public async Task<IEnumerable<TItem>> GetItemsAsync(uint limit,
FilterDefinition<TItem> filter = null,
SortDefinition<TItem> sort = null,
ProjectionDefinition<TItem, TItem> projection = null,
CancellationToken token = default) {
return await CreateFindOperation(limit, filter, sort, projection)
.ToListAsync(token).ConfigureAwait(false);
}
// Helper function that creates a find-operation from some common elements
private IFindFluent<TItem, TItem> CreateFindOperation(uint? limit,
FilterDefinition<TItem> filter = null,
SortDefinition<TItem> sort = null,
ProjectionDefinition<TItem, TItem> projection = null) {
// First, connect to the specific collection in the database
IMongoCollection<TItem> collection = GetCollection();
// Next, create an operation to find the items that are associated with the filter
IFindFluent<TItem, TItem> operation = collection.Find(filter ?? FilterDefinition<TItem>.Empty);
// Now, if the projection operation has been provided then apply it to the
// search and then update the search
if (projection != null) {
operation = operation.Project(projection);
}
// If the sort operation has been provided then modify the search with the sort operation
if (sort != null) {
operation = operation.Sort(sort);
}
// Finally, if the limit has been included in the request then modify the operation to only
// return the first N items associated with the limit; otherwise, return the operation as-is
return limit.HasValue ? operation.Limit((int)limit) : operation;
}
辅助函数还允许我将代码重用于其他检索式函数。
我有一个函数,用于通过 Mongo 数据库中的 ID 检索对象,它看起来像这样:
public async Task<IEnumerable<TItem>> GetItemsAsync(uint limit,
Expression<Func<TItem, bool>> filter = null,
SortDefinition<TItem> sort = null,
ProjectionDefinition<TItem> projection = default,
CancellationToken token = default) {
// First, create the options describing which objects will be returned
var findOptions = new FindOptions<TItem> {
Limit = (int)limit,
Sort = sort,
Projection = projection
};
// Next, connect to the specific collection in the database
IMongoCollection<TItem> collection = GetCollection();
// Now, attempt to find all the items associated with the filter and find options
IAsyncCursor<TItem> cursor = await collection.FindAsync(filter ?? FilterDefinition<TItem>.Empty,
findOptions, token).ConfigureAwait(false);
// Finally, retrieve all the items and return them
return await cursor.ToListAsync(token).ConfigureAwait(false);
}
我遇到的问题是,在我想要 return 文档中的所有字段因此不提供投影的情况下,这会中断。在这种情况下,我得到以下异常:
System.ArgumentNullException: Value cannot be null. (Parameter 'projection')
at MongoDB.Driver.Core.Misc.Ensure.IsNotNull[T](T value, String paramName)
at MongoDB.Driver.KnownResultTypeProjectionDefinitionAdapter`2..ctor(ProjectionDefinition`1 projection, IBsonSerializer`1 projectionSerializer)
at MongoDB.Driver.ProjectionDefinition`2.op_Implicit(ProjectionDefinition`1 projection)
我的问题是:是否有传递投影定义或以编程方式将从 MongoDB 文档检索到的所有字段映射到我的 return 对象的方法?
感谢@Llama 的建议,我得以解决此问题。我将代码重构为如下所示:
public async Task<IEnumerable<TItem>> GetItemsAsync(uint limit,
FilterDefinition<TItem> filter = null,
SortDefinition<TItem> sort = null,
ProjectionDefinition<TItem, TItem> projection = null,
CancellationToken token = default) {
return await CreateFindOperation(limit, filter, sort, projection)
.ToListAsync(token).ConfigureAwait(false);
}
// Helper function that creates a find-operation from some common elements
private IFindFluent<TItem, TItem> CreateFindOperation(uint? limit,
FilterDefinition<TItem> filter = null,
SortDefinition<TItem> sort = null,
ProjectionDefinition<TItem, TItem> projection = null) {
// First, connect to the specific collection in the database
IMongoCollection<TItem> collection = GetCollection();
// Next, create an operation to find the items that are associated with the filter
IFindFluent<TItem, TItem> operation = collection.Find(filter ?? FilterDefinition<TItem>.Empty);
// Now, if the projection operation has been provided then apply it to the
// search and then update the search
if (projection != null) {
operation = operation.Project(projection);
}
// If the sort operation has been provided then modify the search with the sort operation
if (sort != null) {
operation = operation.Sort(sort);
}
// Finally, if the limit has been included in the request then modify the operation to only
// return the first N items associated with the limit; otherwise, return the operation as-is
return limit.HasValue ? operation.Limit((int)limit) : operation;
}
辅助函数还允许我将代码重用于其他检索式函数。