J’ai quatre cours simples
public class Zoo{ public ObjectId Id { get; set; } public List Animals { get; set; } } public class Animal{ public ObjectId Id { get; set; } public ssortingng Name { get; set; } } public class Tiger : Animal{ public double Height { get; set; } } public class Zebra : Animal{ public long SsortingpesAmount { get; set; } }
J’ai créé le sérialiseur personnalisé qui me permet de stocker un object Animal dans une collection distincte (“animaux”).
class MyAnimalSerializer : SerializerBase { public override void Serialize(MongoDB.Bson.Serialization.BsonSerializationContext context, MongoDB.Bson.Serialization.BsonSerializationArgs args, Animal value) { context.Writer.WriteStartDocument(); context.Writer.WriteName("_id"); context.Writer.WriteObjectId(ObjectId.GenerateNewId()); context.Writer.WriteName("_t"); context.Writer.WriteSsortingng(value.GetType().Name); context.Writer.WriteName("Name"); context.Writer.WriteSsortingng(value.Name); switch (value.AnimalType) { case AnimalType.Tiger: context.Writer.WriteName("Height"); context.Writer.WriteDouble((value as Tiger).Height); break; case AnimalType.Zebra: context.Writer.WriteName("SsortingpesAmount"); context.Writer.WriteInt32((value as Zebra).SsortingpesAmount); break; default: break; } context.Writer.WriteEndDocument(); } public override Animal Deserialize(MongoDB.Bson.Serialization.BsonDeserializationContext context, MongoDB.Bson.Serialization.BsonDeserializationArgs args) { context.Reader.ReadStartDocument(); ObjectId id = context.Reader.ReadObjectId(); ssortingng object_type = context.Reader.ReadSsortingng(); ssortingng animal_name = context.Reader.ReadSsortingng(); switch (object_type) { case "Tiger": double tiger_height = context.Reader.ReadDouble(); context.Reader.ReadEndDocument(); return new Tiger() { Id = id, Name = animal_name, Height = tiger_height }; default: long zebra_ssortingpes = context.Reader.ReadInt64(); context.Reader.ReadEndDocument(); return new Zebra() { Id = id, Name = animal_name, SsortingpesAmount = zebra_ssortingpes }; } return null; } }
Ce qui fonctionne bien et me permet aussi des choses comme ça:
MongoDB.Bson.Serialization.BsonSerializer.RegisterSerializer(typeof(Animal), new MyAnimalSerializer()); IMongoCollection collection = db.GetCollection("animals"); var lst = await collection.Find(new BsonDocument()).ToListAsync();
Mais je ne peux pas faire la même chose lorsque les animaux sont stockés dans Zoo et ne peuvent pas désérialiser Zoo de la collection Zoo:
IMongoCollection collection = db.GetCollection("zoocollection"); var lst = await collection.Find(new BsonDocument()).ToListAsync(); //not working here
Est-il possible de créer un sérialiseur de collection personnalisé pour le champ?
public List Animals { get; set; }
Quelqu’un pourrait-il donner un exemple? Merci d’avance.
Avez-vous visité cette page de document ? Il existe également des exemples de classes polymorphes.
Voici mon exemple de stockage d’objects:
public class Zoo { [BsonId] public ObjectId Id { get; set; } public List Animals { get; set; } } [BsonDiscriminator(RootClass = true)] [BsonKnownTypes(typeof(Tiger), typeof(Zebra))] public class Animal { [BsonId] public ObjectId Id { get; set; } public ssortingng Name { get; set; } } public class Tiger : Animal { public double Height { get; set; } } public class Zebra : Animal { public long SsortingpesAmount { get; set; } } public class MongoDocumentsDatabase { /// /// MongoDB Server /// private readonly MongoClient _client; /// /// Name of database /// private readonly ssortingng _databaseName; public MongoUrl MongoUrl { get; private set; } /// /// Opens connection to MongoDB Server /// public MongoDocumentsDatabase(Ssortingng connectionSsortingng) { MongoUrl = MongoUrl.Create(connectionSsortingng); _databaseName = MongoUrl.DatabaseName; _client = new MongoClient(connectionSsortingng); } /// /// Get database /// public IMongoDatabase Database { get { return _client.GetDatabase(_databaseName); } } public IMongoCollection Zoo { get { return Database.GetCollection ("zoo"); } } } class Program { static void Main(ssortingng[] args) { var connectionSsortingng = "mongodb://admin:admin@localhost:27017/testDatabase"; var pr = new Program(); pr.Save(connectionSsortingng); var zoo = pr.Get(connectionSsortingng); foreach (var animal in zoo.Animals) { Console.WriteLine(animal.Name + " " + animal.GetType()); } } public void Save(ssortingng connectionSsortingng) { var zoo = new Zoo { Animals = new List { new Tiger { Height = 1, Name = "Tiger1" }, new Zebra { Name = "Zebra1", SsortingpesAmount = 100 } } }; var database = new MongoDocumentsDatabase(connectionSsortingng); database.Zoo.InsertOneAsync(zoo).Wait(); } public Zoo Get(ssortingng connectionSsortingng) { var database = new MongoDocumentsDatabase(connectionSsortingng); var task = database.Zoo.Find(e => true).SingleAsync(); task.Wait(); return task.Result; } }
Voici comment les objects ont été stockés dans la firebase database (Robomongo)
Et résultat final:
Merci beaucoup Anton Putau pour la solution la plus simple possible.
Mais il y en a un autre. Pour sérialiser des objects manuellement:
public class MyListAnimalSerializer : SerializerBase> { public override void Serialize(MongoDB.Bson.Serialization.BsonSerializationContext context, MongoDB.Bson.Serialization.BsonSerializationArgs args, List value) { context.Writer.WriteStartArray(); foreach (Animal mvnt in value) { context.Writer.WriteStartDocument(); switch (mvnt.GetType().Name) { case "Tiger": //your serialization here break; case "Zebra": //your serialization here break; default: break; } context.Writer.WriteEndDocument(); } context.Writer.WriteEndArray(); } public override List Deserialize(MongoDB.Bson.Serialization.BsonDeserializationContext context, MongoDB.Bson.Serialization.BsonDeserializationArgs args) { context.Reader.ReadStartArray(); List result = new List (); while (true) { try { //this catch block only need to identify the end of the Array context.Reader.ReadStartDocument(); } catch (Exception exp) { context.Reader.ReadEndArray(); break; } var type = context.Reader.ReadSsortingng(); var _id = context.Reader.ReadObjectId(); var name = context.Reader.ReadSsortingng(); if (type == "Tiger") { double tiger_height = context.Reader.ReadDouble(); result.Add(new Tiger() { Id = id, Name = animal_name, Height = tiger_height }); } else { long zebra_ssortingpes = context.Reader.ReadInt64(); result.Add(return new Zebra() { Id = id, Name = animal_name, SsortingpesAmount = zebra_ssortingpes }); } context.Reader.ReadEndDocument(); } return result; } }
Et vous devez simplement annoter le champ IEnumerable pour utiliser votre sérialiseur:
[BsonSerializer(typeof(MyListAnimalSerializer))] public List Animals { get; set; }