MongoDB .NET 驱动程序映射值为空

MongoDB .NET Driver Mapping values as null

我正在使用 MongoDB 驱动程序尝试将 BsonDocument 映射到模型。当我尝试从集合中读取模型时,字符串值为空,日期时间是最小值,枚举是它们的默认值。这是我想从集合中读取的文档:

这是 class 我想将其映射到:

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; }
}

这里是我定义映射的地方:

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);
        });

我使用 MapMember 而不是 AutoMap 因为我不希望 file 成为我模型的一部分。 这是我尝试从集合中读取的代码:

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();
}

这是我在调试时看到的 photos.Find(new BsonDocument()).ToList()

为什么 class 映射不正确?

还有一个相关的问题:我应该在哪里执行映射?文档说要在初始化 MongoDB 连接之前注册 class 映射,所以我在构建主机和 运行 之前在 Program.cs 中进行了注册。那是个好地方吗?

这样做。您甚至不需要指定映射。 mongo driver 负责处理。您的主要问题是数据库字段名称和 class 属性 名称的大小写不匹配。

using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Whosebug
{
    [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();
        }
    }
}

您甚至可以通过像这样注册一个约定包来消除对属性装饰的需要:

ConventionRegistry.Register(
    "MyConvensions",
    new ConventionPack
    {
        new IgnoreExtraElementsConvention(true),
        new CamelCaseElementNameConvention()
    },
    _ => true);