首页 文章

如何使用官方MongoDB C#驱动程序将BsonDocument转换为强类型对象?

提问于
浏览
16

出于单元测试的目的,我'd like to test my class mappings without reading and writing documents into the MongoDB database. To handle special cases such as circular parent / child references and read only properties, I'使用了 BsoncClassMap.RegisterClassMap< MyType>(...) ,其中一些自定义映射覆盖了默认的 AutoMap(); 生成的映射 .

有没有人知道如何将BsonDocument转换为所需的强类型对象而不进行数据库往返?当进出数据存储时,驱动程序正在执行此操作 . 我的目标是使用MongoDB C#驱动程序在内部使用的相同逻辑来测试与C#域对象之间的序列化到BsonDocument .

我能够使用Bson扩展方法 ToBsonDocument() 将C#对象转换为BsonDocument吗?我缺乏的那一块是与过程相反的 - 基本上是 BsonDocument.ToObject< MyType>(); .

这是官方MongoDB C#驱动程序的最新版本吗?它似乎应该是 - 我想知道我是否只是盲目而且错过了显而易见的事实 .

4 回答

  • 30

    MongoDB驱动程序确实提供了一种从Bson反序列化到您的类型的方法 . BsonSerializer 可以在 MongoDB.Bson.SerializationMongoDB.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;}
    }
    

    我希望这有帮助 .

  • 1

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

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

    而你只需要“教师”实体的“课程”,你可以使用:

    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” .

  • 1

    如果要将从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"
    
  • 0

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

相关问题