Skip to main content
SEMastery
Data Accessbeginner

Getting Started With MongoDB in EF Core: A Beginner's Guide

A friendly beginner guide to using MongoDB with EF Core in .NET. Learn setup, DbContext, UseMongoDB, CRUD, mapping, and the limits you must know.

13 min readUpdated March 18, 2026

Getting Started With MongoDB in EF Core: A Beginner's Guide

Think about two kinds of cupboards in an Indian home.

The first cupboard has fixed shelves. Every shelf has a label: "spices", "rice", "snacks". Each item must go in its exact slot. This is like a SQL database with tables, rows, and columns. Everything has a fixed place.

The second cupboard is a big trunk (peti). You drop in a whole gift box. Inside that box are sweets, a card, and a small toy, all together. You do not break them apart into different shelves. You keep the whole box as one unit. This is like MongoDB. It stores a full "document" together, like one gift box.

Now, EF Core (Entity Framework Core) is the helper that .NET developers already use to talk to the fixed-shelf cupboard. The good news is that EF Core can now also talk to the trunk-style cupboard, MongoDB. You use the same friendly EF Core code you already know, but your data is stored as documents.

This guide goes slow. Short sentences. Real examples. By the end you will have a tiny app that saves and reads data from MongoDB using EF Core.

What is MongoDB, in one minute

MongoDB is a document database. Instead of tables and rows, it stores documents. A document looks a lot like JSON. Documents live inside collections, which are like folders full of documents.

Here is a simple comparison so the words make sense.

SQL worldMongoDB worldPlain meaning
DatabaseDatabaseThe whole box of data
TableCollectionA folder of similar items
RowDocumentOne single item
ColumnFieldOne piece of an item
Primary key_id fieldThe unique tag on an item

So when you save a Blog object in MongoDB, it becomes one document inside a blogs collection. No splitting into many tables. The whole object stays together.

What is the MongoDB EF Core provider

EF Core does not know how to speak "MongoDB" by itself. It needs a translator. That translator is a NuGet package called MongoDB.EntityFrameworkCore. We call it the provider.

The provider sits in the middle. You write normal EF Core code. The provider turns it into MongoDB commands.

Where the provider sits between your code and MongoDB

Keep this picture in your head. Your code talks to EF Core. EF Core talks to the provider. The provider uses the official MongoDB driver underneath. The driver talks to the server. Five clean steps.

A few facts to set your expectations right away:

  • The provider went stable (GA) in May 2024. It is real and ready to use.
  • It works with EF Core 8 or 9 on .NET 8+, and EF Core 10 on .NET 10+.
  • Your MongoDB server should be 5.0 or newer.
  • MongoDB is now an LTS-friendly choice for .NET 10 apps, so this is a good time to learn it.

Step 1: Create the project and add the package

First make a small console app and add the provider.

// In your terminal:
// dotnet new console -n MongoEfDemo
// cd MongoEfDemo
// dotnet add package MongoDB.EntityFrameworkCore

That one package is enough. It pulls in EF Core and the MongoDB driver for you. You do not need to add them separately.

Here is the flow of setting up from zero to your first saved document.

From empty folder to first document

Create app
Add package
Define entity
Make DbContext
Save data

Steps

1

Create app

dotnet new console

2

Add package

MongoDB.EntityFrameworkCore

3

Define entity

A plain C# class

4

Make DbContext

Use UseMongoDB

5

Save data

Add then SaveChanges

The simple path a beginner follows

Step 2: Define your entity

An entity is just a plain C# class. Each object becomes one document. Let us model a simple blog.

using MongoDB.Bson;
using MongoDB.EntityFrameworkCore;
 
public class Blog
{
    public ObjectId Id { get; set; }       // MongoDB's natural key (_id)
    public string Title { get; set; } = "";
    public string Author { get; set; } = "";
    public int Likes { get; set; }
    public List<string> Tags { get; set; } = new();  // arrays are fine
}

Notice the Id is an ObjectId. In MongoDB, every document has a special _id field. ObjectId is MongoDB's own 12-byte unique value. The provider maps your Id property to _id automatically. You can also use string or Guid for the key if you prefer, but ObjectId is the most natural choice.

Also notice the List<string> Tags. In SQL you would need a separate table for tags. In MongoDB the list just lives inside the same document. That is the "keep the whole gift box together" idea in action.

Step 3: Create the DbContext

The DbContext is your session with the database. It is the same idea you use in any EF Core app. The one new thing is the UseMongoDB call.

using Microsoft.EntityFrameworkCore;
using MongoDB.Driver;
 
public class BloggingContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
 
    private readonly MongoClient _client;
    private readonly string _databaseName;
 
    public BloggingContext(MongoClient client, string databaseName)
    {
        _client = client;
        _databaseName = databaseName;
    }
 
    protected override void OnConfiguring(DbContextOptionsBuilder options)
    {
        options.UseMongoDB(_client, _databaseName);
    }
 
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Tell EF Core which collection this entity lives in.
        modelBuilder.Entity<Blog>().ToCollection("blogs");
    }
}

Two important lines:

  • UseMongoDB(client, databaseName) connects EF Core to MongoDB. It takes a MongoClient and the database name. That is all the provider needs to start.
  • ToCollection("blogs") says: store Blog documents in a collection named blogs. If you skip this, EF Core picks a name for you, but naming it yourself is clearer.

Step 4: Save and read data

Now the fun part. Let us create a client, build the context, and do basic CRUD (Create, Read, Update, Delete).

using MongoDB.Driver;
 
// One client for the whole app. Reuse it. Do not make a new one per request.
var client = new MongoClient("mongodb://localhost:27017");
 
using var db = new BloggingContext(client, "demo");
 
// CREATE
var blog = new Blog
{
    Title = "My first MongoDB post",
    Author = "Priya",
    Likes = 0,
    Tags = new() { "mongodb", "efcore" }
};
db.Blogs.Add(blog);
db.SaveChanges();
 
// READ
var popular = db.Blogs
    .Where(b => b.Likes >= 0)
    .OrderByDescending(b => b.Likes)
    .ToList();
 
// UPDATE
blog.Likes += 1;
db.SaveChanges();
 
// DELETE
db.Blogs.Remove(blog);
db.SaveChanges();

If you have used EF Core with SQL Server before, this looks almost identical. That is the whole point. You keep your EF Core habits. Only the storage changes.

When you call SaveChanges, EF Core hands the work to the provider. The provider turns your changes into MongoDB write commands. Here is that journey for a single save.

What happens when you call SaveChanges

Mapping: telling EF Core how fields look

By default the provider does a good job on its own. But sometimes you want control over names and shapes. You have two ways: attributes on the class, or the fluent API in OnModelCreating.

Here is a quick map of the common tools.

You want to...Attribute wayFluent API way
Pick the collection name[Table("blogs")].ToCollection("blogs")
Rename a field in the document[Column("t")] or [BsonElement("t")].HasElementName("t")
Mark the key[Key] or [BsonId].HasKey(...)
Skip a property[BsonIgnore].Ignore(...)

A small example using attributes:

using System.ComponentModel.DataAnnotations.Schema;
using MongoDB.Bson.Serialization.Attributes;
 
[Table("blogs")]
public class Blog
{
    [BsonId]
    public ObjectId Id { get; set; }
 
    [Column("t")]              // stored as "t" in the document
    public string Title { get; set; } = "";
 
    [BsonIgnore]               // not stored at all
    public string CacheKey { get; set; } = "";
}

Renaming fields to short names like "t" can save space when you have millions of documents. But for a beginner, clear names are better. Use renaming only when you have a real reason.

Embedded documents: the MongoDB superpower

This is where MongoDB feels different from SQL. You can put one object inside another. This is called an owned entity or embedded document.

Imagine a blog post with an author profile. In SQL you would make an Authors table and join. In MongoDB you can store the author right inside the blog document.

public class Blog
{
    public ObjectId Id { get; set; }
    public string Title { get; set; } = "";
    public Author Author { get; set; } = new();   // embedded
}
 
public class Author
{
    public string Name { get; set; } = "";
    public string City { get; set; } = "";
}

In the context, you mark it as owned:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .ToCollection("blogs")
        .OwnsOne(b => b.Author);
}

Now the author lives inside the blog document, like a smaller box inside the gift box. One read gets you everything. No join needed. This is faster for reads when the data always travels together.

One blog document holds the author inside it

Things the provider cannot do (yet)

This part is important. MongoDB is a document database, not a SQL database. So some EF Core features simply do not apply. Knowing this early saves you hours of confusion.

  • No migrations. There is no schema to migrate. Collections appear automatically when you first write to them. So no dotnet ef migrations add.
  • No foreign keys or alternate keys. Documents are self-contained. You model relationships by embedding or by storing an id and looking it up yourself.
  • No Select projections (yet). You query full entities. To shape data, do it in memory or use the raw MongoDB driver.
  • No spatial data, no time series collections, no Atlas full-text search through the provider. For those, use the MongoDB driver directly.

The provider does support a lot: Where, OrderBy, ThenBy, Skip, Take, First, Single, and aggregates like Count, Sum, Min, Max, and Average. Arrays, lists, dictionaries of simple types, and embedded entities all work. So for everyday CRUD apps, you are well covered.

Here is a simple way to decide what to use for a tricky query.

Provider or raw driver?

Need a query
Basic CRUD or filter?
Use EF Core provider
Projection or search?
Use MongoDB driver

Steps

1

Need a query

Start here

2

Basic CRUD or filter?

Where, OrderBy, Count

3

Use EF Core provider

Stay in EF Core

4

Projection or search?

Select, text, geo

5

Use MongoDB driver

Drop down for power

A quick decision guide when a query gets advanced

Setting it up cleanly with dependency injection

In a real ASP.NET Core app, you do not create the client by hand each time. You register things once at startup. The golden rule: one MongoClient for the whole app, shared as a singleton. The client holds a pool of connections, so one is enough.

var builder = WebApplication.CreateBuilder(args);
 
// One shared client for the whole app.
builder.Services.AddSingleton(_ =>
    new MongoClient(builder.Configuration.GetConnectionString("Mongo")));
 
// Register the DbContext using that client.
builder.Services.AddDbContext<BloggingContext>((sp, options) =>
{
    var client = sp.GetRequiredService<MongoClient>();
    options.UseMongoDB(client, "demo");
});
 
var app = builder.Build();

Now any controller or service can ask for BloggingContext and EF Core wires it up. This keeps your code tidy and your connections healthy.

A mental model of the whole flow

Let us put all the pieces together in one picture so you can see the full journey from a web request to MongoDB and back.

Full request flow in an ASP.NET Core app

Read it slowly. A request comes in. The controller uses the DbContext. EF Core and the provider translate the work. The driver carries it to the server. The server replies. The response goes back to the user. Same pattern you already know from SQL EF Core, just a document store underneath.

Common beginner mistakes to avoid

A short list of traps, so you skip the pain:

  • Making a new MongoClient per request. Do not. Make one, share it. A fresh client every time wastes connections and slows the app.
  • Looking for migrations. There are none here. Just write data and the collection is born.
  • Expecting joins. Think in documents. Embed data that belongs together, or store an id and fetch the other document yourself.
  • Trying Select projections. Not supported yet. Query the entity, then shape it in memory, or use the driver.
  • Forgetting indexes. EF Core does not auto-create your performance indexes. For real apps, create indexes (often through the MongoDB driver) on fields you filter or sort by a lot.

When should you choose MongoDB with EF Core

MongoDB with EF Core is a great fit when your data is naturally "document shaped": a blog with its comments, an order with its line items, a user with their profile and settings. When data travels together, embedding is fast and simple.

It is a weaker fit when you have many complex relationships and need heavy joins, strict transactions across many tables, or reporting with lots of projections. For those, a relational database with SQL EF Core may serve you better. Both are good tools. Pick the one that matches the shape of your data.

Quick recap

  • MongoDB is a document database. It stores whole objects as documents inside collections, like keeping a full gift box together.
  • The MongoDB.EntityFrameworkCore package is the provider that lets EF Core talk to MongoDB. One package pulls in everything you need.
  • You configure it with UseMongoDB(client, databaseName) inside your DbContext, and pick collections with ToCollection("name").
  • Basic CRUD and LINQ filters (Where, OrderBy, Skip, Take, Count, Sum) work just like normal EF Core.
  • Embedded documents with OwnsOne let you store related data inside one document. No joins needed.
  • Know the limits: no migrations, no foreign keys, no Select projections yet. Drop to the MongoDB driver for advanced needs.
  • Use one shared MongoClient as a singleton, and remember to add indexes for speed in real apps.

References and further reading

Related Posts