首页 > 解决方案 > MongoDB .NET 驱动程序映射值为 null

问题描述

我正在使用 MongoDB Driver 尝试将 BsonDocument 映射到模型。当我尝试从集合中读取模型时,字符串值为 null,DateTimes 是最小值,枚举是它们的默认值。这是我想从集合中阅读的文档:

在此处输入图像描述

这是我想将其映射到的类:

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()在此处输入图像描述

为什么类没有正确映射?

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

标签: c#mongodbmongodb-.net-driver

解决方案


像这样做。你甚至不需要指定映射。mongo 司机会处理这个问题。您的主要问题是 db 字段名称和类属性名称的大小写不匹配。

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

你甚至可以通过注册一个约定包来消除对属性装饰的需要,如下所示:

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

推荐阅读