Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deserialize a BsonDocument object back to class

How do I deserialize a BsonDocument object back to the class after getting it from the server?

QueryDocument _document = new QueryDocument("key", "value"); MongoCursor<BsonDocument> _documentsReturned = _collection.FindAs<BsonDocument>(_document);  foreach (BsonDocument _document1 in _documentsReturned) {     //deserialize _document1     //? } 

Do I deserialize using a BsonReader?

like image 737
iefpw Avatar asked Feb 28 '12 08:02

iefpw


2 Answers

There are three ways actually:

1.Specify type you want to load directly in FindAs<>

var docs = _collection.FindAs<MyType>(_document); 

2.Deserialize document via BsonSerializer:

BsonSerializer.Deserialize<MyType>(doc); 

3.Map bson document manually to your class:

var myClass = new Mytype(); myClass.Name = bsonDoc["name"].AsString; 

For most cases you are okay with first approach. But sometimes, when your documents is unstructured, you may need third approach.

like image 177
Andrew Orsich Avatar answered Sep 22 '22 01:09

Andrew Orsich


For big applications and which has some structured data, it's recommended to use your custom model while creating and getting the data instead of using BsonDocument.

Creating a model is an important step for deserialization.

Helpful annotations to remember while creating your model:

  • add id property in model. Try to use [BsonId] attribute for good practice:
  • Create a property with annotation as [BsonExtraElements] this will be used to hold any extra elements found during deserialization.
  • you can use [BsonElement] to specify the elementName.
  • [BsonIgnoreIfDefault] - Initializes a new instance of the BsonIgnoreIfDefaultAttribute class

Sample Model structure, where I tried to cover maximum cases. I have created a base class for _id property just for better architecture, but you can use directly in MyModel class as well.

    public abstract class BaseEntity     {         // if you'd like to delegate another property to map onto _id then you can decorate it with the BsonIdAttribute, like this         [BsonId]         public string id { get; set; }     }      public class MyModel: BaseEntity     {         [BsonElement("PopulationAsOn")]         public DateTime? PopulationAsOn { get; set; }              [BsonRepresentation(BsonType.String)]         [BsonElement("CountryId")]         public int CountryId { get; set; }          [Required(AllowEmptyStrings = false)]         [StringLength(5)]         [BsonIgnoreIfDefault]         public virtual string CountryCode { get; set; }          [BsonIgnoreIfDefault]         public IList<States> States { get; set; }          [BsonExtraElements]         public BsonDocument ExtraElements { get; set; }     } 

Now to Deserialise, directly use your model while calling FindAsync like this:

cursor = await _collection.FindAsync(filter,  new FindOptions<MyModel, MyModel>()  { BatchSize = 1000, Sort = sort }, ct); 
like image 28
KushalSeth Avatar answered Sep 23 '22 01:09

KushalSeth