Reputation: 646
I'm using MongoDB Driver to try and map BsonDocument to a model. When I try to read models from a collection, string values are null, DateTimes are the minimum value, and enums are their default value. Here is a document I'd like to read from a collection:
This is the class I'd like to map it to:
public class PhotoModel
{
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public string Name { get; set; }
[BsonSerializer(typeof(PhotoCategorySerializer))]
public PhotoCategory Category { get; set; }
public string Description { get; set; }
public string UserID { get; set; }
public DateTime Created { get; set; }
}
Here is where I define the mapping:
BsonClassMap.RegisterClassMap<PhotoModel>(cm =>
{
cm.MapMember(c => c.Id);
cm.MapMember(c => c.Name);
cm.MapMember(c => c.Description);
cm.MapMember(c => c.Category);
cm.MapMember(c => c.UserID);
cm.MapMember(c => c.Created);
});
I use MapMember
instead of AutoMap
because I don't want file
to be a part of my model.
This is the code where I try to read from the collection:
public class PhotoRepository : IPhotoRepository
{
private readonly IMongoCollection<PhotoModel> photos;
public PhotoRepository(IMongoClient mongoClient)
{
photos = mongoClient.GetDatabase("photo-share").GetCollection<PhotoModel>("photos");
}
public IEnumerable<PhotoModel> GetAllPhotos() => photos.Find(new BsonDocument()).ToList();
}
This is what I see when I debug photos.Find(new BsonDocument()).ToList()
:
Why is the class not mapped properly?
Also, a related question: where should I perform the mappings? The docs said to register class maps before initializing a MongoDB connection, so I do it in Program.cs before the host is built and run. Is that a good place for it?
Upvotes: 1
Views: 1353
Reputation: 5679
do it like this. you don't even need to specify mapping. mongo driver takes care of that. your main problem is the mismatched casing of db field names and class property names.
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace StackOverflow
{
[BsonIgnoreExtraElements]
public class PhotoModel
{
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
[BsonElement("name")]
public string Name { get; set; }
[BsonElement("category"), BsonSerializer(typeof(PhotoCategorySerializer))]
public PhotoCategory Category { get; set; }
[BsonElement("description")]
public string Description { get; set; }
[BsonElement("userID")]
public string UserID { get; set; }
[BsonElement("created")]
public DateTime Created { get; set; }
}
internal static class Program
{
private static readonly IMongoClient client =
new MongoClient("mongodb://localhost");
private static readonly IMongoCollection<PhotoModel> photoCollection =
client.GetDatabase("photo-share").GetCollection<PhotoModel>("photos");
private static async Task Main()
{
IEnumerable<PhotoModel> photos = await photoCollection.Find(_ => true).ToListAsync();
}
}
}
you could even eliminate the need for the attribute decorations by registering a convension pack like so:
ConventionRegistry.Register(
"MyConvensions",
new ConventionPack
{
new IgnoreExtraElementsConvention(true),
new CamelCaseElementNameConvention()
},
_ => true);
Upvotes: 1