web-dev-qa-db-fra.com

Comment convertir un BsonDocument en un objet fortement typé avec le pilote officiel MongoDB C #?

Pour les tests unitaires, j'aimerais tester mes correspondances de classes sans lire ni écrire de documents dans la base de données MongoDB. Pour gérer des cas particuliers tels que les références parent/enfant circulaires et les propriétés en lecture seule, j'ai utilisé BsoncClassMap.RegisterClassMap< MyType>(...) avec certains mappages personnalisés remplaçant les mappages générés par défaut par AutoMap();.

Est-ce que quelqu'un sait comment convertir un BsonDocument en l'objet fortement typé souhaité sans effectuer un aller-retour vers la base de données? C'est ce que fait le pilote pour aller au magasin de données et en revenir. Mon objectif serait d'utiliser la même logique que celle utilisée par le pilote MongoDB C # en interne pour tester la sérialisation vers/depuis un objet de domaine C # dans un BsonDocument.

Je peux utiliser la méthode d'extension Bson ToBsonDocument() pour convertir un objet C # en un BsonDocument? Ce qui me manque, c'est l'inverse du processus - essentiellement une BsonDocument.ToObject< MyType>();.

Est-ce possible avec la dernière version du pilote officiel MongoDB C #? Il semble que cela devrait être - je me demande si je suis juste aveugle et que je manque l'évidence.

16
user3769062

Le pilote MongoDB fournit une méthode de désérialisation de Bson à votre type. La BsonSerializer se trouve dans MongoDB.Bson.dll, dans l'espace de noms MongoDB.Bson.Serialization.

Vous pouvez utiliser la méthode BsonSerializer.Deserialize<T>(). Un exemple de code serait

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 est défini comme

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

J'espère que ça aide.

30
Pete Garafano

Si vous avez besoin d'une partie d'objet, par exemple: Vous avez l'entité Enseignant:

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

Et cours d'entité:

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

Et vous n'avez besoin que de "Cours" de l'entité "Enseignant", vous pouvez utiliser:

var db = conection.GetDatabase("school");
var collection = db.GetCollection<Teacher>("teachers"); // Or your collection Name
string mailForSearch="[email protected]"; // 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);

Maintenant, vous avez une liste de cours de taecher et convertissez la réponse BsonDocument en "IEnumerable".

1
Locoucla

Voici un moyen simple de mapper les lignes extraites de mongoDB à une classe de votre code.

//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" : "[email protected]" }"

// 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 "[email protected]"
1
Anil Garlapati

Utilisez le mot clé yield pour renvoyer les données que vous souhaitez.

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