Skip to content

Instantly share code, notes, and snippets.

@dbones
Last active March 25, 2024 21:01
Show Gist options
  • Select an option

  • Save dbones/fbaa210afeda6c599e52d20a59ce8989 to your computer and use it in GitHub Desktop.

Select an option

Save dbones/fbaa210afeda6c599e52d20a59ce8989 to your computer and use it in GitHub Desktop.
Laters EF
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Data.Common;
using Laters;
using Laters.AspNet;
using Laters.ClientProcessing;
using Laters.Data.EntityFrameworkCore;
using Laters.Minimal.Application;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
//connection to share
builder.Services.AddScoped<DbConnection>(_ => {
var connectionString = "Host=postgres;Port=5432;Database=laters;Username=application;Password=ABC123!!";
return new Npgsql.NpgsqlConnection(connectionString);
});
//applications db context
builder.Services.AddDbContext<TodoItemDbContext>((provider, options) => {
var connection = provider.GetRequiredService<DbConnection>();
options.UseNpgsql(connection);
});
builder.WebHost.ConfigureLaters((context, setup)=>
{
//reference ourself for the demo
setup.Configuration.WorkerEndpoint = "http://localhost:5056";
//setting up EF as the storage
setup.UseStorage<UseEntityFramework>(ef =>
{
//using the same connection as above
ef.ConnectionFactory = provider => provider.GetRequiredService<DbConnection>();
ef.ApplyOptions =(_, connection, options) =>
{
//injecting the connection, and setting up the migration to be in this assembly
options.UseNpgsql(connection, b=> b.MigrationsAssembly("EpicTodoList.Service"));
};
});
});
var app = builder.Build();
app.UseLaters();
app.UseMiddleware<TransactionMiddleware>();
app.MapGet("/todo-items", (TodoItemDbContext context) =>
{
var items = context.TodoItems.ToList();
return Task.FromResult(items);
});
app.MapPost("/todo-items", ([FromBody]TodoItem item, TodoItemDbContext context) =>
{
item.Id ??= Guid.NewGuid().ToString("D");
context.TodoItems.Add(item);
return Results.Created($"/todo-items/{item.Id}", item);
});
app.MapPut("/todo-items/{id}", async (
[FromBody]TodoItem item,
string id,
TodoItemDbContext context,
ISchedule schedule) =>
{
var existingItem = await context.TodoItems.FindAsync(id);
if (existingItem == null)
{
return Results.NotFound();
}
existingItem.Title = item.Title;
existingItem.Details = item.Details;
existingItem.Completed = item.Completed;
if (existingItem.Completed)
{
var removeDateTime = DateTime.UtcNow.AddMinutes(1);
schedule.ForLater(new RemoveTodoItem { Id = existingItem.Id }, removeDateTime);
}
return Results.NoContent();
});
app.MapHandler<RemoveTodoItem>(async (JobContext<RemoveTodoItem> ctx, TodoItemDbContext context) =>
{
var item = await context.TodoItems.FindAsync(ctx.Payload!.Id);
if (item != null)
{
context.TodoItems.Remove(item);
}
await Task.CompletedTask;
});
app.Run();
public class TransactionMiddleware
{
private readonly RequestDelegate _next;
public TransactionMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(
HttpContext context,
TodoItemDbContext todoDbContext,
LatersDbContext latersDbContext,
DbConnection connection)
{
await _next(context);
if(connection.State != ConnectionState.Open)
{
connection.Open();
}
using var tx = connection.BeginTransaction(IsolationLevel.Serializable);
todoDbContext.Database.UseTransaction(tx);
latersDbContext.Database.UseTransaction(tx);
await todoDbContext.SaveChangesAsync();
await latersDbContext.SaveChangesAsync();
tx.Commit();
}
}
public class RemoveTodoItem
{
public string Id { get; set; } = string.Empty;
}
public class TodoItem
{
public string Id { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public string Details { get; set; } = string.Empty;
public bool Completed { get; set; } = false;
}
public class TodoItemDbContext : DbContext
{
public TodoItemDbContext(DbContextOptions<TodoItemDbContext> options) : base(options)
{
}
public DbSet<TodoItem> TodoItems { get; set; } = null!;
}
@dbones

dbones commented Mar 25, 2024

Copy link
Copy Markdown
Author

dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Laters
dotnet add package Laters.Data.EntityFrameworkCore

dotnet ef migrations add InitialCreate --context TodoItemDbContext
dotnet ef database update --context TodoItemDbContext

dotnet ef migrations add InitialCreate --context LatersDbContext
dotnet ef database update --context LatersDbContext

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment