I have the following model class and its DTO:
public class User
{
public string FullName { get; set; }
public string DomainEmail { get; set; }
}
public class UserDto
{
public string Name { get; set; }
public string Email { get; set; }
}
And I have to do this query with aggregation:
var matchStage = new BsonDocument(Match, new BsonDocument
{
{ nameof(User.FullName), new BsonDocument(Eq, "Foo bar") }
});
var pipeline = new[] { matchStage };
var result = await _collection.Aggregate<UserDto>(pipeline).ToListAsync();
return result;
My problem is that I don't know how to map the properties from my model to my dto. This is a basic example, but in my real scenario, my model has more than 25 fields and the query is really bigger. I've created a projection, but I don't know how to apply this projection to my .Aggregate
:
var projection = Builders<User>.Projection.Expression(m => new UserDto
{
Name = m.FullName,
Email = m.DomainEmail
});
var result = await _collection
.Aggregate<UserDto>(pipeline)
.Project(projection) // This doesn't work
.ToListAsync();
return result;
Mapped classes:
CreateMap<User, UserDto>()
.ForMember(u => u.Name, opts => opts.MapFrom(u => u.FullName))
.ForMember(u => u.Email, opts => opts.MapFrom(u => u.DomainEmail));
Is there a way to solve this?
I am not sure, but I think you are missing the projection
var result = await _collection
.Aggregate<PipelineDefinition<User, UserDto>>(pipeline)
.ToListAsync().ConfigureAswait(false);
This assumes you have registered the user:
IMongoCollection<User>
Based on your answer you need to map the properties manually:
var config = new MapperConfiguration(cfg => {
cfg.CreateMap<User, UserDto>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.FullName))
.ForMember(dest => dest.Email, opt => opt.MapFrom(src => src.DomainEmail));
});
IMapper mapper = config.CreateMapper();