Entity Framework Core supports the Database-First approach via the Scaffold-DbContext command of the Package Manager Console and the dotnet ef dbcontext scaffold command of the .NET CLI. These commands scaffold a DbContext and entity type classes for the collections of a MongoDB database.
This tutorial shows how to create a simple console application powered by Entity Framework Core and dotConnect for MongoDB, using the Database-First approach. In less than 10 minutes, you will have a ready-to-use data access layer for your business objects.
This tutorial requires the following:
MongoDB collections have no fixed schema: dotConnect for MongoDB reads a sample of the documents of each collection (the Describe Amount connection string parameter, 100 by default) and builds the columns of the collection from the fields it finds. Therefore, the collections to scaffold must contain documents.
Run the following script in mongosh. It creates the sample database with two collections: customers, whose documents hold an embedded document (address), an array of embedded documents (phones), and an array of values (tags), and orders, which refer to the customers by their _id.
const d = db.getSiblingDB("sample");
const eve = ObjectId();
const tom = ObjectId();
d.customers.insertMany([
{
_id: eve,
name: "Eve Adams",
email: "[email protected]",
address: { city: "Rome", street: "Via Appia 12" },
phones: [ { kind: "home", number: "+39 06 1234567" }, { kind: "mobile", number: "+39 333 7654321" } ],
tags: [ "vip", "newsletter" ]
},
{
_id: tom,
name: "Tom Baker",
email: "[email protected]",
address: { city: "London", street: "Baker Street 221b" },
phones: [ { kind: "mobile", number: "+44 7700 900123" } ],
tags: [ "newsletter" ]
}
]);
d.orders.insertMany([
{ customerId: eve, orderDate: ISODate("2026-09-14T10:30:00Z"), total: NumberDecimal("129.90"), quantity: 3, paid: true },
{ customerId: eve, orderDate: ISODate("2026-10-02T16:05:00Z"), total: NumberDecimal("45.00"), quantity: 1, paid: false },
{ customerId: tom, orderDate: ISODate("2026-10-20T08:15:00Z"), total: NumberDecimal("310.50"), quantity: 5, paid: true }
]);
|
After creating a new project, add the necessary NuGet packages to it.
If you want to use the .NET CLI, install the Microsoft.EntityFrameworkCore.Design package instead of Microsoft.EntityFrameworkCore.Tools, and the dotnet-ef tool of the same version.
dotnet add package Devart.Data.MongoDB.EFCore dotnet add package Microsoft.EntityFrameworkCore.Design dotnet tool install --global dotnet-ef |
To create a model from the database, run the Scaffold-DbContext command and pass a connection string and the Devart.Data.MongoDB.EFCore provider as parameters. For example, run the following command in the Package Manager Console:
Scaffold-DbContext "Host=localhost;Database=sample;User Id=user;Password=pwd;License Key=***" Devart.Data.MongoDB.EFCore -OutputDir Models -Context SampleContext |
Alternatively, use the .NET CLI.
dotnet ef dbcontext scaffold "Host=localhost;Database=sample;User Id=user;Password=pwd;License Key=***" Devart.Data.MongoDB.EFCore -o Models --context SampleContext |
If you have other collections in your database, you can use the -Tables parameter (--table for the .NET CLI) to filter the list of collections that are added to the model.
Scaffold-DbContext "Host=localhost;Database=sample;User Id=user;Password=pwd;License Key=***" Devart.Data.MongoDB.EFCore -OutputDir Models -Context SampleContext -Tables customers,orders |
As a result, a context class and entity classes are generated based on the customers and orders collections. The embedded document address becomes the owned type Address, the array of embedded documents phones becomes a collection of the owned type Phone, and the array of values tags becomes List<string>.
Entity classes are simple classes that represent the data stored in the database. The ObjectId values (_id, customerId) are strings. The Decimal128 field total is a string by default; set the Decimal128 Mapping connection string parameter to get decimal or double instead. Value-type properties are nullable (DateTime?, int?, bool?), since a MongoDB document may lack any field. For the complete list of types, see Entity Framework Core Data Type Mapping.
The context represents a session with the database and lets you query and save instances of the entity classes.
You can comment out or delete the warning about the connection string.
Now you can use the model to retrieve and modify data.
Open your Program.cs file and replace its content with the following code:
using ConsoleApplication1.Models;
using (var db = new SampleContext())
{
// Creating a new customer and saving it to the database
var customer = new Customer
{
Name = "Ann Lee",
Email = "[email protected]",
Address = new Address { City = "Rome", Street = "Via Veneto 5" },
Phones = new List<Phone> { new Phone { Kind = "mobile", Number = "+39 347 1112233" } },
Tags = new List<string> { "vip" }
};
db.Customers.Add(customer);
var count = db.SaveChanges();
Console.WriteLine("{0} records saved to database, new _id: {1}", count, customer.Id);
// Retrieving and displaying data
Console.WriteLine();
Console.WriteLine("Customers from Rome:");
foreach (var c in db.Customers.Where(c => c.Address.City == "Rome").OrderBy(c => c.Name))
Console.WriteLine("{0} | {1} | {2}", c.Name, c.Address.Street, string.Join(", ", c.Tags));
Console.WriteLine();
Console.WriteLine("VIP customers with a mobile phone:");
foreach (var c in db.Customers.Where(c => c.Tags.Contains("vip") && c.Phones.Any(p => p.Kind == "mobile")))
Console.WriteLine("{0} | {1}", c.Name, c.Phones.First(p => p.Kind == "mobile").Number);
Console.WriteLine();
Console.WriteLine("Paid orders:");
var paid = from o in db.Orders
join c in db.Customers on o.CustomerId equals c.Id
where o.Paid == true
orderby o.OrderDate
select new { c.Name, o.OrderDate, o.Total };
foreach (var o in paid)
Console.WriteLine("{0:yyyy-MM-dd} | {1} | {2}", o.OrderDate, o.Name, o.Total);
} |
The queries filter by a field of the embedded document (c.Address.City), by an element of the array of values (c.Tags.Contains), and by the elements of the array of embedded documents (c.Phones.Any), and join the two collections by the customer ObjectId.
After this, on the Debug menu, select Start Without Debugging. The application prints the following:
The _id of the new customer is different on each run.