Database

MongoDB with C#: Deep Dive

In the previous article in this series on MongoDB, I explained how to get started with the C# driver in a simple Windows console application. I analyzed several options for generating your own domain classes and mapping them to their underlying MongoDB document-oriented schemata. In this third and final installment in the series, I dive into using the MongoDB C# driver in an ASP.NET MVC Web application. To follow along, you need to understand the concepts introduced in the previous article.

Matching Document Field Names to Domain Class Requirements

Up to this point in the series, I've shown examples of the MongoDB mapping configurations and the operations to apply when you use your own C# domain classes. The documents stored in the collections don't follow the name conventions that are appropriate for the fields in the domain classes, and therefore, it's necessary to tweak mappings. However, one of the great advantages of MongoDB and its C# driver is that you can reduce the required number of mapping configurations to a minimum by following the most appropriate conventions according to the needs of your domain classes.

I want to develop an ASP.NET MVC Web application in C# and I need the properties in each POCO (or Plain Old C# Object) to use Pascal case. Thus, for example, instead of using relase_date as the field name for a document in the games collection, I can just use the same name that I require for the property, ReleaseDate. This way, I can remove the specific mapping configuration for the ReleaseDate property in my domain class and reduce maintenance.

Removing the mapping information with field names for the documents in the collections has a price. If someone changes the name of a property in a domain class while refactoring code, there are going to be undesired side effects in the operations with the related collection. For example, if someone renames the ReleaseDate property to FirstReleaseDate for the Game class, the new insert operations to the games collection performed through the refactored C# application will add a different field to each new document: FirstReleaseDate instead of ReleaseDate. No exceptions will occur during the inserts because each document might have a completely different schema without problems in any MongoDB collection. In addition, when retrieving old documents in the games collection through the refactored C# application, FirstReleaseDate won't be filled up with values from the document. The old documents have the FirstRelease field, which won't be mapped to any property in the refactored domain class.

Another option is to override the conventions that determine the decisions that the MongoDB C# drivers makes when a class is automatically mapped. For example, you can create a new MongoDB.Bson.Serialization.Conventions.ConventionProfile instance, and call its SetIdGeneratorConvention to specify the default mechanism to use for ID generation. Then, you can apply the ConventionProfile to all the classes that belong to a specific namespace. However, overriding the conventions requires you to manually address low-level serialization configuration issues.

So, whenever you decide to reduce mapping information to the minimum by following conventions or overriding them, you must be careful with refactorings that would be safe when not working with automatically mapped domain classes.

Creating a Data Layer for an ASP.NET MVC 4 Web Application

Let's work with a complete example of an ASP.NET MVC 4 Web application that interacts with a MongoDB database and reduces mapping information to the minimum. To keep the example simple, I'll focus on the data layer. I've reduced the necessary code by using the data domain classes as ViewModels. If you already worked with ASP.NET MVC 3 or 4, you know that it is a good idea to have your ViewModels completely decoupled from the data domain classes and types. Thus, we don't consider the Views and ViewModels as pieces of code that follow best practices. In addition, to keep code simple and easy to understand, I haven't included all the necessary exception handling blocks. My main goal here is simply to explain the features of the MongoDB C# driver.

The sample ASP.NET MVC Web application has the following requirements:

Next, add the following two references to the new class library, as I explained in the previous article:

MongoDB.Bson.dll.

MongoDB.Driver.dll.

The RetrogamesWeb.Data project includes interfaces and classes for the entities within the Entities folder. The classes that define the entities include the minimum possible annotations for mappings. As mentioned, the entities will also be used as ViewModels, but the code doesn't include data annotations to avoid confusion. (However, you can create the required ViewModels, add the mapping code, and include the data annotations there.) I explained the IMongoEntity interface and the entities in "MongoDB with C#."

The project includes interfaces and classes that provide repository services for the entities within the Serivces folder. I'll explore these interfaces and classes as I provide their source code. In addition, there is a MongoConnectionHandler class that performs the steps necessary to get a reference to the collection object from the Mongo database object, but in a generic way that all the services can use by following conventions.

Notice that the only attribute specified for the properties is [BsonDateTimeOptions(DateOnly = true)]. This way, the ReleaseDate consists of a date only (the time is always going to be 12:00:00 AM in the field value).

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task.
However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Video

This month's Dr. Dobb's Journal

This month,
Dr. Dobb's Journal is devoted to mobile programming. We introduce you to Apple's new Swift programming language, discuss the perils of being the third-most-popular mobile platform, revisit SQLite on Android
, and much more!