【问题标题】:How to convert a BsonDocument into a strongly typed object with the official MongoDB C# driver?如何使用官方 MongoDB C# 驱动程序将 BsonDocument 转换为强类型对象?
【发布时间】:2021-03-17 00:52:11
【问题描述】:

出于单元测试的目的,我想测试我的类映射,而不是在 MongoDB 数据库中读取和写入文档。为了处理循环父/子引用和只读属性等特殊情况,我使用了BsoncClassMap.RegisterClassMap< MyType>(...) 和一些覆盖默认AutoMap(); 生成的映射的自定义映射。

有谁知道如何将 BsonDocument 转换为所需的强类型对象而不需要往返数据库?驱动程序在往返数据存储时执行此操作。我的目标是使用 MongoDB C# 驱动程序在内部使用的相同逻辑来测试从 C# 域对象到/从 C# 域对象到 BsonDocument 的序列化。

我可以使用 Bson 扩展方法ToBsonDocument() 将 C# 对象转换为 BsonDocument 吗?我缺少的部分是该过程的逆过程 - 本质上是 BsonDocument.ToObject< MyType>();

最新版本的官方 MongoDB C# 驱动程序可以做到这一点吗?看起来应该是这样 - 我想知道我是不是只是瞎了眼,错过了明显的东西。

【问题讨论】:

    标签: c# mongodb


    【解决方案1】:

    MongoDB 驱动程序确实提供了一种从 Bson 反序列化为您的类型的方法。 BsonSerializer 可以在 MongoDB.Bson.dllMongoDB.Bson.Serialization 命名空间中找到。

    您可以使用BsonSerializer.Deserialize<T>() 方法。一些示例代码是

    var obj = new MyClass { MyVersion = new Version(1,0,0,0) };
    var bsonObject = obj.ToBsonDocument();
    var myObj = BsonSerializer.Deserialize<MyClass>(bsonObject);
    Console.WriteLine(myObj);
    

    MyClass 定义为

    public class MyClass
    {
        public Version MyVersion {get; set;}
    }
    

    我希望这会有所帮助。

    【讨论】:

    • 谢谢!这正是我一直在寻找的。感谢您的帮助。
    • 对于那些不知道的人,您可以通过在 c# 文件顶部键入 using MongoDB.Bson.Serialization; 来导入 BsonSerializer.Deserialize
    【解决方案2】:

    如果您想将从 mongoDB 获取的行映射到代码中的类,一种直接的方法如下

    //Connect and Query from MongoDB
    var db = client.GetDatabase("blog");
    var col = db.GetCollection<BsonDocument>("users");
    var result = await col.Find(new BsonDocument("Email",model.Email)).ToListAsync();
    
    //read first row from the result
    var user1 = result[0];
    result[0] would be say "{ "_id" : ObjectId("569c05da09f251fb0ee33f5f"), "Name" : "fKfKWCc", "Email" : "pujkvBFU@kQKeYnabk.com" }"
    
    //A user class with name and email
    User user = new User();
    
    // assign 
    User.Name = user1[1].ToString();      // user1[1] is "fKfKWCc"    
    User.Email = user1[2].ToString();      // user1[2] is "pujkvBFU@kQKeYnabk.com"
    

    【讨论】:

      【解决方案3】:

      如果您需要对象的一部分,例如: 你有实体教师:

      public class Teacher
      {
      public string Mail {get; set;}
      public IEnumerable<Course> Courses {get; set;}
      public string Name {get; set;}
      }
      

      和实体课程:

      public class Course
      {
      public int CurseCode {get; set;}
      public string CourseName {get; set;}
      }
      

      你只需要来自“Teacher”实体的“Courses”,你可以使用:

      var db = conection.GetDatabase("school");
      var collection = db.GetCollection<Teacher>("teachers"); // Or your collection Name
      string mailForSearch="teacher@school.com"; // param for search in linq
      var allCoursesBson = collection.Find(x => x.Mail == mailForSearch).Project(Builders<Teacher>.Projection.Include(x => x.Courses).Exclude("_Id")).ToList();
      // allCoursesBson is BsonDocument list, then use a first BsonDocument an convert to string for convert to IEnumerable<Courses> type with  BsonSerializer.Deserialize
      string allCoursesText = resp.FirstOrDefault()[0].ToString();
      IEnumerable<Courses> allCourses = BsonSerializer.Deserialize<IEnumerable<Courses>>(allCoursesText);
      

      现在,您有一个来自 taecher 的课程列表,并将 BsonDocument 答案转换为“IEnumerable”。

      【讨论】:

        【解决方案4】:

        使用yield关键字返回你想要的数据。

        public IEnumerable<string> GetMongoFields(string collectionName)
                {
                    var connectionString = ConfigurationManager.ConnectionStrings[DbConfig.GetMongoDb()].ConnectionString;
                    var databaseName = MongoUrl.Create(connectionString).DatabaseName;
                    MongoClient client = new MongoClient(connectionString);
                    var server = client.GetServer();
                    var db = server.GetDatabase(databaseName);
        
                    var collection = db.GetCollection<BsonDocument>(collectionName);
                    var list = collection.FindAll().ToList();
        
                   yield return list.ToJson();
                }
        

        【讨论】:

        • Json 字符串的可枚举不是强类型对象,这是原始问题所要求的。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-05
        相关资源
        最近更新 更多