Monday, May 25, 2015

MongoDB and .NET POCOs

While creating MongoDB documents, used nested objects and nested collections to take advantage of the way the POCO objects can be stored in the MongoDb documents doing away with the typical SQL impedance mismatch that ORMs try to solve.

By having nested objects within the same document, there are no need for JOINs and any constraints can live within the documents in a collection, just like relationships can exist between different tables in a relational database. That is feel free to use nested collections like arrays within your document or POCO object.

The MongoDB driver takes care of serializing your POCOs to MongoDB documents (internally stored as binary BSON documents in MongoDB) and deserializing them back to POCO objects without any noticebale friction, making programming very simple against MongoDB once the appropriate driver (mongo C# driver in our case) is installed in your project.

Avoid laying out your POCO objects based on your experience of creating POCO objects for SQL (multiple lean POCO entities with associations that turn into foreign key constraints). So stop replicating SQL in your POCO objects when working with MongoDB. So in MongoDB, take advantage of creating your rich domain models with nested objects, arrays and nested collections. Akin to pre-joining your SQL data across several tables out of the box!

So any data you typically work with at the same time, combine them into one single document for your document oriented design. The concept of an aggregate root in Domain Driven Design theory maps very nicely to Documents.

TIPS:

1) While declaring a decimal type field in your .NET POCO object, make sure you decorate it with the [BsonRepresenation(BsonType.Double)] attribute to convert it to the BSON double type. Otherwise the decimal CLR type is converted to string making any comparisons or indexing against the field string oriented and slow. Example, you want to sort and filter on a decimal Price field.

2) Also in the default serialization .NET characters and enums are represented as integers when a string may be desirable. So keep that in mind.

3) For DateTime, Mongo always uses UTC while .NET can use UTC as well as Local. This can have side-effects if we are not explicit about what date time type we want in our POCO object. So if using .NET Local time, always use the attribute [BsonDateTimeOptions(Kind = DateTimeKind=Local)]. Then when we deserialize the object back into .NET type using the BsonSerializer.Deserializer<T>, it will use the Local time zone correctly and not UTC.

4) Use DateOnly=true in your BsonDateTimeOptions if we want to ignore the time portion.

5) Use BsonIgnore attribute to ignore fields in the document

6) If you want to use a different field name rather than the default _id field, use BsonId attribute

7) At the class level, decorate with [BsonIgnoreExtraElements] if we want to remove fields from the document, without worrying with a file format exception that will be otherwise thrown by the Bson driver.





No comments:

Post a Comment