Entity Framework Core (EF Core) to popularny ORM dla platformy .NET, który pozwala programistom pracować z bazami danych za pomocą obiektów C# zamiast pisania surowych zapytań. Dzięki MongoDB EF Core Provider te same znane wzorce można teraz stosować z bazą NoSQL, jaką jest MongoDB.
W tym artykule dowiesz się, jak połączyć MongoDB z EF Core, poznasz kluczowe koncepcje i zobaczysz praktyczny przykład, który możesz zaadaptować do własnych projektów.
Dlaczego MongoDB + EF Core?
MongoDB przechowuje dane jako elastyczne dokumenty w formacie JSON (BSON) w kolekcjach – bez sztywnych schematów tabel. EF Core z kolei daje programistom .NET spójne API do dostępu do danych z zapytaniami LINQ, śledzeniem zmian i podejściem code-first. Połączenie obu technologii oznacza elastyczność MongoDB z wygodnymi wzorcami EF Core.
Główne zalety MongoDB EF Core Provider:
- Podejście code-first – definiujesz modele w C#, a EF Core zajmuje się resztą
- Wsparcie LINQ – zapytania do MongoDB przy użyciu standardowej składni LINQ
- Śledzenie zmian (change tracking) – automatyczne wykrywanie modyfikacji encji
- Dokumenty zagnieżdżone – natywne wsparcie dla obiektów osadzonych
- Znajome API – jeśli znasz EF Core z SQL Server, przejście jest płynne
Rozpoczęcie pracy
Wymagania
- .NET 7.0+ SDK
- Konto MongoDB Atlas (dostępny darmowy plan) lub lokalna instancja MongoDB
- Ulubione IDE (Visual Studio, VS Code, Rider)
Instalacja pakietu NuGet
dotnet add package MongoDB.EntityFrameworkCore
Pakiet automatycznie instaluje MongoDB C# Driver i EF Core jako zależności.
Praktyczny przykład: Katalog produktów
Zbudujemy prosty katalog produktów, aby zademonstrować wszystkie operacje CRUD.
1. Definicja modelu
using MongoDB.Bson;
using MongoDB.EntityFrameworkCore;
namespace MyApp.Models
{
[Collection("products")]
public class Product
{
public ObjectId Id { get; set; }
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
public string Category { get; set; } = string.Empty;
public List<string> Tags { get; set; } = new();
}
}
Atrybut [Collection("products")] mapuje tę klasę na kolekcję products w MongoDB. Zwróć uwagę na właściwość Tags – MongoDB obsługuje tablice natywnie, co w relacyjnej bazie wymagałoby osobnej tabeli.
2. Tworzenie DbContext
using Microsoft.EntityFrameworkCore;
using MyApp.Models;
namespace MyApp.Data
{
public class ProductDbContext : DbContext
{
public DbSet<Product> Products { get; init; }
public ProductDbContext(DbContextOptions options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Product>();
}
}
}
3. Konfiguracja połączenia
using MongoDB.Driver;
using Microsoft.EntityFrameworkCore;
using MyApp.Data;
// Tworzenie klienta MongoDB
var mongoClient = new MongoClient("mongodb+srv://<user>:<password>@cluster0.xxxxx.mongodb.net");
// Konfiguracja DbContext z MongoDB
var dbContextOptions = new DbContextOptionsBuilder<ProductDbContext>()
.UseMongoDB(mongoClient, "my_store")
.Options;
var db = new ProductDbContext(dbContextOptions);
4. Operacje CRUD
Tworzenie (Create)
var newProduct = new Product
{
Name = "Klawiatura mechaniczna",
Price = 149.99m,
Category = "Elektronika",
Tags = new List<string> { "peryferia", "gaming", "biuro" }
};
db.Products.Add(newProduct);
db.SaveChanges();
Console.WriteLine($"Dodano produkt z ID: {newProduct.Id}");
Odczyt (Read)
// Wszystkie produkty z danej kategorii
var elektronika = db.Products
.Where(p => p.Category == "Elektronika")
.OrderBy(p => p.Price)
.ToList();
foreach (var product in elektronika)
{
Console.WriteLine($"{product.Name} – {product.Price:C}");
}
// Pojedynczy produkt po warunku
var klawiatura = db.Products
.FirstOrDefault(p => p.Name == "Klawiatura mechaniczna");
Aktualizacja (Update)
var productToUpdate = db.Products
.FirstOrDefault(p => p.Name == "Klawiatura mechaniczna");
if (productToUpdate != null)
{
productToUpdate.Price = 129.99m;
productToUpdate.Tags.Add("wyprzedaz");
db.SaveChanges();
}
Usuwanie (Delete)
var productToDelete = db.Products
.FirstOrDefault(p => p.Name == "Klawiatura mechaniczna");
if (productToDelete != null)
{
db.Products.Remove(productToDelete);
db.SaveChanges();
}
Użycie w ASP.NET Core
W prawdziwej aplikacji webowej rejestrujesz DbContext w Program.cs:
// Program.cs
var connectionString = builder.Configuration.GetConnectionString("MongoDB");
var databaseName = builder.Configuration["MongoDBSettings:DatabaseName"];
builder.Services.AddDbContext<ProductDbContext>(options =>
options.UseMongoDB(connectionString ?? "", databaseName ?? ""));
A w appsettings.json:
{
"ConnectionStrings": {
"MongoDB": "mongodb+srv://<user>:<password>@cluster0.xxxxx.mongodb.net"
},
"MongoDBSettings": {
"DatabaseName": "my_store"
}
}
Następnie wstrzykujesz kontekst do kontrolerów lub serwisów:
public class ProductsController : Controller
{
private readonly ProductDbContext _db;
public ProductsController(ProductDbContext db)
{
_db = db;
}
public IActionResult Index()
{
var products = _db.Products.OrderBy(p => p.Name).Take(50).ToList();
return View(products);
}
}
Warto wiedzieć
- Brak wsparcia dla relacji – MongoDB EF Core Provider nie obsługuje jeszcze właściwości nawigacyjnych ani relacji między encjami. Można to obejść, przechowując powiązane ID i odpytując ręcznie.
- Dokumenty zagnieżdżone działają świetnie – zamiast joinów modeluj dane zagnieżdżone jako właściwości encji.
- Zaawansowane funkcje – do Atlas Search lub Vector Search używaj MongoDB C# Driver bezpośrednio obok EF Core.
- Śledzenie zmian – działa tak samo jak z bazami relacyjnymi; do MongoDB wysyłane są tylko zmodyfikowane pola.
Podsumowanie
MongoDB EF Core Provider pozwala programistom .NET korzystać ze znanego API EF Core z bazą MongoDB, łącząc najlepsze cechy obu światów. Definiujesz modele w C#, używasz LINQ do zapytań, a EF Core zajmuje się resztą. W przypadku większości operacji CRUD doświadczenie jest niemal identyczne jak przy użyciu EF Core z SQL Server – z dodatkową elastycznością bazy dokumentowej.