Fast Document Database In .NET With Marten
Tags: postgres, marten, nosql, dotnet
Published: 2023-09-16 10:51:28

---
title: Fast Document Database In .NET With Marten
published: true
date: 2022-12-17 00:00:00 UTC
tags: postgresql,marten,nosql,dotnet
canonical_url: https://www.milanjovanovic.tech/blog/fast-document-database-in-net-with-marten
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x9trvmvzyv19xvcza0hy.png
---
Did you know you can turn **PostgreSQL** into a fully-fledged **Document database**?

**Marten** is a **.NET** library that allows developers to use the **PostgreSQL** database as both a **document database** and a fully-featured **event store**.

You don't need to install anything else to be able to use **PostgreSQL** as a **document database** , outside of the Nuget package. **Marten** relies on the **JSONB** support available since **PostgreSQL** 9.4.

In this week's newsletter, I want to introduce you to the basics of working with **Marten** and show you how easy it is to get started.

Let's dive in.

## Installing And Configuring Marten

What are you going to need to start using **PostgreSQL** as a **Document datbase**?

Other than a running instance of **PostgreSQL** , of course, you will need to install the **Marten** Nuget package:

```csharp
dotnet add package Marten
```

**Marten** can build the required database schema and necessary tables on the fly, and I suggest using this approach in development. For a production environment, you definitely want to apply schema changes on your own with migration scripts.

To register **Marten** with dependency injection, you need to call the `AddMarten`method.

Here's an example **Marten** configuration inside of a **.NET 7** application:

```csharp
builder.Services.AddMarten(options =>
{
    options.Connection(builder.Configuration.GetConnectionString("Marten"));
});
```

This will register a few services with dependency injection:

- `IDocumentStore` - used to create sessions, generate schema migrations, and do bulk inserts
- `IDocumentSession` - used for read and write operations
- `IQuerySession` - used for read operations

Let's see how we can work with documents using **Marten**.

## Storing Documents With Marten

Storing documents in the database is very straightforward. You need to create a new `DocumentStore` instance, and open an `IDocumentSession` which exposes methods for storing and persisting documents.

Let's see how we can store a `Product` document:

```csharp
var store = DocumentStore.For("Connection string to PostgreSQL");

using var session = store.OpenSession();

var product = new Product
{
    Name = "C# 11 and .NET 7 - Modern Cross-Platform Fundamentals",
    Price = 46.87
};

session.Store(product);

await session.SaveChangesAsync();
```

We're creating a new `DocumentStore` instance which we use to open a session to **PostgreSQL**. And then we just call `Store` and pass in the `Product` instance. Note that **Marten** will populate the`Product.Id` at this point. **Marten** can populate keys of `Guid`,`int`, `long`, and other data types. It uses the HiLo algorithm for numeric keys. Finally, when we call `SaveChangesAsync` the`Product` is serialized into **JSON** and persisted as a document.

An important thing to be aware of is that the `IDocumentSession`created by `OpenSession` doesn't track changes on the entities automatically. You need to create a session with dirty checking enabled by calling `DirtyTrackedSession` on the `DocumentStore` to enable automatic change detection.

## Querying Documents With Marten

**Marten** has rich support for querying documents in the database. You can write and execute queries using **LINQ** , which you are familiar with if you worked with **EF Core**. And you can also write and execute **SQL** queries, because it's still a **PostgreSQL** database underneath.

Here's an example query to return products that have a higher price than the one which is specified:

```csharp
var store = DocumentStore.For("Connection string to PostgreSQL");

using var session = store.QuerySession();

var products = session.Query<Product>().Where(p => p.Price > 9.99).ToList();
```

**Marten** also has support for:

- Including related documents
- Batched queries
- Paging
- Full text search

## Advanced Options With Marten

**Marten** can utilize the full capabilities **PostgreSQL** has to offer, notably transactions and indexing. **Marten** sessions are transactional by default, either all of the documents are persisted together or none of them are. And you can configure indexes on your documents for faster queries.

**Marten** isn't just a **document database** on top of **PostgreSQL**!

You have fully-fledged support for **event sourcing** with **Marten** , as well as projections. This makes it a perfect choice for implementing **CQRS**. But this is a topic for a separate newsletter.

## Closing Thoughts

I'm absolutely amazed with [Marten](https://martendb.io/) and what it has to offer. And **PostgreSQL** is also my favorite database, so it's like a match made in heaven. I don't get too excited about learning new technologies, but **Marten** has been an endless source of joy this past week.

I still need to explore a few more topics before I can consider it for production use:

- Schema migrations
- Relationships and foreign keys
- Advanced configuration options

Considering that **PostgreSQL** is cheaper than most **document databases** , I think using **Marten** is an interesting alternative. And if you are familiar with **SQL** databases, you can still use all of that knowledge.

* * *

**P.S. Whenever you're ready, there are 2 ways I can help you:**

1. [**Pragmatic Clean Architecture:**](https://www.milanjovanovic.tech/pragmatic-clean-architecture?utm_source=dev.to&utm_medium=website&utm_campaign=cross-posting) This comprehensive course will teach you the system I use to ship production-ready applications using Clean Architecture. Learn how to apply the best practices of modern software architecture. [**Join 950+ students here.**](https://www.milanjovanovic.tech/pragmatic-clean-architecture?utm_source=dev.to&utm_medium=website&utm_campaign=cross-posting)

2. [**Patreon Community:**](https://www.patreon.com/milanjovanovic) Think like a senior software engineer with **access to the source code** I use in my YouTube videos and **exclusive discounts** for my courses. [**Join 820+ engineers here.**](https://www.patreon.com/milanjovanovic)