DEV Community

James Turner for Turner Software

Posted on • Updated on • Originally published at turnerj.com

Mongo what now?

Have you ever had your main side project spin out a side project of its own? I don't know how often this happens with others but it is seems to be a reoccurring theme with my projects.

Before I explain what this side side project is, let me explain a little how I got here.

The original side project

For the last number of years I've been working on building my own analytics tools to help manage and analyse brands. This itself deserves its own post at some point in the future when I eventually launch it but for now, the important part is to know a little about how development progressed with it.

My original concept for this was to be a PHP/MySQL site based around a little-known framework called SilverStripe. Should have been easy to build as it is one of the main technology stacks I use to build websites for clients. The further I went into development though, the further it didn't feel like the right technology for the job.

So what was PHP/MySQL changed to C#/MySQL - not exactly the most natural duo. Not long after that, for similar reasons as before, I changed again to C#/SQL.

Because I must just enjoy rewriting code, I changed again - this time, now C#/MongoDB.

These changes weren't just for kicks - it was the build up of little things along the way that made me want to do each of these changes. With the side project now using C# and MongoDB, this brings us to today.

C# + MongoDB = MongoDB C# Driver?

My experience with C# and databases have primarily been around the good ol' Linq2SQL interface which for the most part has done what I've needed to without issues. That said when I was working with C#/SQL for that original side project, I came to love Entity Framework - particularly the "Code First" experience and how you interact with collections.

An example of an EF "Code First" approach:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class MyContext : DbContext 
{
    public MyContext() : base() { }
    public DbSet<Person> People { get; set; }
}

...

using (var ctx = new MyContext())
{
    var entity = new Person() { Name = "James" };
    ctx.People.Add(entity);
    ctx.SaveChanges();           
}

Enter fullscreen mode Exit fullscreen mode

MongoDB has a fully-featured C# driver and can probably do anything you want with the database. To me though, its downside is the API interface to it. In comparison to above, interfacing with the driver looks more like this:

public class Person
{
    public ObjectId Id { get; set; }
    public string Name { get; set; }
}

...

var client = new MongoClient("mongodb://localhost:27017");
var database = client.GetDatabase("foo");
var collection = database.GetCollection<Person>("bar");

collection.InsertOne(new Person { Name = "James" });
Enter fullscreen mode Exit fullscreen mode

Now that is not an inherently bad API or anything, it just wasn't how I liked dealing with databases. What I really wanted was that Entity Framework interface but with a MongoDB backend.

If you're an Entity Framework Core fan, there does seem to be people working on proper MongoDB providers for it however back when I started working on this, that was not available. In addition to that though, my original side project is still stuck in .NET Framework, not Core.

So what did I do? I came up with an original name for my MongoDB "Entity Framework"-like library and got to work.

MongoFramework

Derivative is the new original

It may not be the first piece of code I have published for the world to see but it is probably the one that is most important to me right now.

What I wanted to build was a basic wrapper for the official MongoDB C# driver, making it feel like I was working with Entity Framework. Once I got the basics working, that is when I wanted to start being clever.

That MongoDB C# driver is good but there are some things that were cumbersome out-of-the-box. For example, performing document (aka. entity) updates required you to either use this builder/filter system and specify the keys and values that you updated OR you replace the whole document. Not liking either option, I set to build change tracking and support diff-updates in MongoFramework so you the developer doesn't need to worry.

Another example was how there is no "changeset" support in the official driver - the second you call InsertOne, it has sent that through to the DB. After a few iterations of changeset support in MongoFramework, it can now do a single BulkWrite call with all the changes in a particular MongoDbSet.

Still a Work-In-Progress

Like many side projects, MongoFramework is still a work-in-progress. There are many more features I want to add like GridFS, async reads and DB transaction support.

Even with MongoDB providers now available in EF Core, I think MongoFramework still has its place - if not in your next project, it has a place in my heart. ❤️

GitHub logo TurnerSoftware / MongoFramework

An "Entity Framework"-like interface for MongoDB

MongoFramework

An "Entity Framework"-like interface for MongoDB

AppVeyor Codecov NuGet Codacy Badge

Overview

MongoFramework tries to bring some of the nice features from Entity Framework into the world of MongoDB.

Some of the major features include:

  • Entity mapping for collections, IDs and properties through attributes
  • Indexing through attributes (including text and geospatial)
  • Entity change tracking
  • Changeset support (allowing for queuing multiple DB updates to run at once)
  • Diff-updates (only changes to an entity to be written)
  • Entity Buckets (clustering of small documents together, improving index performance)
  • Runtime type discovery (serialize and deserialize without needing to specify every "known" type)

MongoFramework is currently built on-top of the official MongoDB C# driver.

Extensions

These extensions are official packages that enhance the functionality of MongoFramework, integrating it with other systems and tools.

MongoFramework.Profiling.MiniProfiler

NuGet

Supports profiling database reads and writes, pushing the data into MiniProfiler.

Documentation

Core Entity Mapping

The core mapping of entities and their properties…

Top comments (0)