在使用mongo c#驱动程序(v2.7.2)聚合和投影时,我试图避免将模型手动映射到视图模型。
不是手动进行投影的映射
var projection = Builders<Model>.Projection.Expression(x => new ViewModel {
A = x.A,
B = x.B
// ...more properties
});
我想使用AutoMapper进行映射
var projection = Builders<Model>.Projection.Expression(x => _mapper.Map<ViewModel>(x));
实际上,当我将它用于像这样的find()操作时,这是可行的
var result = mongoCollection
.Find(Builders<Model>.Filter.Empty)
.Project(projection)
.ToList();
但是当我在aggregate()上使用相同的投影时
var result = mongoCollection
.Aggregate()
.Project(projection)
.ToList();
它抛出ArgumentOutOfRangeException
发生异常:CLR / System.ArgumentOutOfRangeException 抛出异常:“ System.ArgumentOutOfRangeException” System.Private.CoreLib.dll:'索引超出范围。一定是 非负数且小于集合的大小。'
首先,我想知道为什么使用AutoMapper进行映射对find()起作用,而不对聚合()起作用?
还有在这种情况下是否可以使用AutoMapper,或者是否有其他方法可以映射到目标类而无需显式反序列化结果客户端?
答案 0 :(得分:1)
也许参加聚会有点晚,但我设法整合了它。 (function UseArrayDestructuring2() {
let a = 1;
let b = 2;
// Use array destructuring to change the 3 statements below into 1 statement.
// You should not need a temporary variable anymore.
let tmp = a;
a = b;
b = tmp;
// Don't make changes below this line
expect(a).toEqual(2);
expect(b).toEqual(1);
的问题在于它是客户端投影。
为了将 automapper 用于服务器端投影,必须将 automapper 生成的 var projection = Builders<Model>.Projection.Expression(x => _mapper.Map<ViewModel>(x));
转换回 IQueryable<T>
。
我的扩展方法:
IMongoQueryable<T>
用法:
public static class MongoDbExtensions
{
public static IMongoQueryable<TDestination> ProjectTo<TSource, TDestination>(this IQueryable<TSource> query, AutoMapper.IMapper autoMapper) =>
query.ProjectTo<BookListDTO>(autoMapper.ConfigurationProvider) as IMongoQueryable<TDestination>;
}