Documentation

Development

Database Migrations

The project by default uses Entity Framework Core (often called EF Core) to interact with the database.

Dapper is a great alternative if you prefer using raw SQL and want to avoid the overhead of migrations.

I do recommend sticking with EF Core, as it's an extremely powerful library. It simplifies data access, supports advanced features like migrations, LINQ, change tracking, and works well with complex domain models - all while giving you the flexibility to drop down to raw SQL when needed.

EF Core Migrations are great because they let you version and evolve your database schema safely and consistently alongside your application code.

Let's start by creating out first Domain Entiity in ShipDotnet.Domain/Products/Product.cs .

public class Product : Entity, IAggregateRoot
{
	public string Name { get; private set; }
	public string? Description { get; private set; }

	private Product()
	{
		// EF
	}

	public Product(string name)
	{
		Name = Guard.Against.NullOrWhiteSpace(name);
	}

	public Product(string name, string? description)
	{
		Name = Guard.Against.NullOrWhiteSpace(name);
		Description = description;
	}
}

Great, now let's add Products to
ShipDotnet.Infrastructure/Persistance/IDbContext.cs and
ShipDotnet.Infrastructure/Persistance/ApplicationDbContext.cs .

public DbSet<Product> Products { get; set; }

Fire up terminal or console and navigate to tools in this git repo:

cd tools

Use a tool to add mnigration:

./ef add AddProduct

You should see:

Build started...
Build succeeded.
Database path Data Source=database.db
Done. To undo this action, use 'ef migrations remove'

You will also notice new migration file has been added:

ShipDotnet.Infrastructure/Migrations/20250611162535_AddProduct.cs

EF Core has detected new Product entity and created a class that will create the corresponding table in the database:

Next, let's make sure those changes are applied to our database

./ef update

You should get the following output:

Build started...
Build succeeded.
Database path Data Source=database.db
Done.