EntityFrameworkCore.
Postgres, SqlServer, Sqlite are supported with EntityFrameworkCore, we have written a provider to make it work with Laters (and applied minimal testing with Postgres)
Overview.
Laters supplies its own DbContext, and this is designed to work with your applications DbContext
It does this via sharing the same Connection and Transaction

This allows us to achieve an all-or-nothing apply/commit to the database.
Configuration.
NOTE
This configuration will show how do to this with Postgres, however, you can apply almost the same code to SqlServer or Sqlite.
Nuget
You can add this support via Nuget
dotnet add package Laters.Data.EntityFrameworkCoreServices - Connection
The connection is to be shared with your DbContext and Laters
//this is the connection we will share between the contexts
builder.Services.AddScoped(provider =>
{
var connectionString = "host=postgres;database=laters;password=ABC123!!;username=application";
var connection = new Npgsql.NpgsqlConnection(connectionString);
return (DbConnection)connection;
});You can use the IDbConnectionFactory if you want.
Services - App DbContext
When adding your DbContext, remember to inject the DbConnection into the UseXXX
//the todo context
builder.Services.AddDbContext<TodoItemDbContext>((provider, options) =>
{
var connection = provider.GetRequiredService<DbConnection>();
options.UseNpgsql(connection);
});HostBuilder - Laters
- 1️⃣ - pass in
UseEntityFrameworkto theUseStoragemethod, and this will set up the storage - 2️⃣ - Setup the
DbConnectionto use, you can see it's the same connection as before. - 3️⃣ - Setup the
Optionsfor theLatersDbContext, and inject theconnection.
builder.WebHost.ConfigureLaters((context, setup) =>
{
//configure Laters
//...
// 1️⃣
setup.UseStorage<UseEntityFramework>(ef => {
// 2️⃣
ef.ConnectionFactory = provider => provider.GetRequiredService<DbConnection>();
// 3️⃣setup the laters dbcontext
ef.ApplyOptions = (_, connection, options) =>
{
options.UseNpgsql(connection, b => b.MigrationsAssembly("EpicTodoList"));
};
});
});DbContext
create your application's DbContext
- 1️⃣ - supply a
constructorwhich takes in a typedDbContextOptions.
public class TodoItemDbContext : DbContext
{
// 1️⃣
public TodoItemDbContext(DbContextOptions<TodoItemDbContext> options) : base(options)
{
}
public DbSet<TodoItem> TodoItems { get; set; } = null!;
}ASP.NET
Middleware
This depends on how you want to manage the commit across the DbContexts
The following is using middleware to synchronize the transaction across the 2 DbContexts at the end of any HTTP Request.
public class TransactionMiddleware
{
readonly RequestDelegate _next;
public TransactionMiddleware(
RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(
HttpContext context,
LatersDbContext latersDbContext,
TodoItemDbContext todoDbContext,
DbConnection connection)
{
await _next(context);
if(connection.State != ConnectionState.Open)
connection.Open();
using var tx = connection.BeginTransaction(IsolationLevel.Serializable);
latersDbContext.Database.UseTransaction(tx);
todoDbContext.Database.UseTransaction(tx);
latersDbContext.SaveChanges();
todoDbContext.SaveChanges();
tx.Commit();
}
}Register
Add UseLaters to apply all the Laters middleware, and the TransactionMiddleware so we can handle the transaction correctly.
app.UseLaters();
app.UseMiddleware<TransactionMiddleware>();Migrations
as you are running 2 contexts, you will need to create the migration for both.
Application
The following will create the migration for you application's code
dotnet ef migrations add InitialCreate -p EpicTodoList --context TodoItemDbContextApply the update to your database.
dotnet ef database update -p EpicTodoList --context TodoItemDbContextLaters
NOTE
The migrations for laters needs to be setup in the UseEntityFramework, shown above
The following will create the migration Laters DbContext
dotnet ef migrations add InitialCreate -p Laters.Data.EntityFramework --context LatersDbContextApply the update to your database.
dotnet ef database update -p EpicTodoList --context LatersDbContext