In the February 2019 issue of MSDN Magazine (Exploring the Multi-Model Capability of Azure Cosmos DB Using Its API for MongoDB), my Data Points column explored working with the MongoDB model of Azure Cosmos DB using the mongocsharpdriver. I started by working against a local instance of MongoDB and then the Azure instance. But the column was a little bit long so I cut out a few extraneous sections . So I’m placing them here and linking to this blog post from the article.
In the article I used an IMongoCollection object to query and store data into the database. You must specify a type for the collection object to serialize and deserialize. In the article I typed the collection to my classes, e.g., Collection<Ship>. It’s also possible to type the collection generically to a BsonDocument. Here’s some information about that and a little bit of code.
Typing Collections to BsonDocument
Another path for mapping is to use a BsonDocument typed collection object that isn’t dependent on a particular type. This would allow you to have more generic methods. But it also means manually serializing and deserializing your objects, which is easy using ToBsonDocument for serializing:
var coll = db.GetCollection<BsonDocument> ("Ships"); coll.InsertOne (ship.ToBsonDocument());
Given that the documents have discriminators, you can then specify a type in your query to retrieve specific types although, by default, hierarchies don’t get accounted for. The article refers to documentation on polymorphism for the C# API. Here’s the link. Check to learn how to properly implement polymorphism in more detail . The following code will only pull back documents where _t matches the configured discriminator for Ship into ships and for DecommissionedShip into dShips:
var coll = db.GetCollection<BsonDocument> ("Ships"); var ships = coll.AsQueryable().OfType<Ship>().ToList(); var dShips = coll.AsQueryable() .OfType<DecommissionedShip>().ToList();
Encapsulating the MongoClient, Database and Collection
Specifying a typed collection instance repeatedly, as I did in the article demos, can become a drag. You could set them up in advance, for example in a class that acts as a context for interacting with the database, as shown here:
public class ExpanseContext { public IMongoDatabase ExpanseDb { get; private set; } public IMongoCollection<Ship> Ships { get; private set; } public IMongoCollection<Character> Characters {get;private set;} public ExpanseContext() { ExpanseDb=new MongoClient().GetDatabase("ExpanseDatabase"); Ships=ExpanseDb.GetCollection<Ship>("ships"); Characters=ExpanseDb.GetCollection<Character>("ships"); } }
This refactored code to insert a document is much more readable:
private static void InsertViaContext () { var context = new ExpanseContext (); var ship = new Ship { Name = "Agatha King" }; context.Ships.InsertOne (ship); }
Sign up for my newsletter so you don't miss my conference & Pluralsight course announcements!
That’s a great blog! I have really found this Information is really useful. It is very Interesting and written in a good manner. Please keep sharing, I look forward to reading more.