JamesWilliams
JamesWilliams

Reputation: 49

EF Core change tracking and Blazor Server

I'm struggling to find a good pattern to work with EF Core and Blazor Server.

From my research, the best thing to do is using DI and DbContextFactory. Then wrap every operation in its own DbContext.

Program.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContextFactory<ApplicationDbContext>();
}

OrderService.cs:

private readonly IDbContextFactory<ApplicationDbContext> _contextFactory;

public OrderService(IDbContextFactory<ApplicationDbContext> contextFactory)
{
    _contextFactory = contextFactory;
}

public async Task<Order[]> GetAllOrders()
{
    using var ctx = _contextFactory.CreateDbContext();
    return await _context.Orders.Include(o=>o.OrderLines).ToArrayAsync();
}

But the problem with this, is the DbContext will be disposed, and I'll lose any change tracking abilities.

For example if the data is tied to an editable DataTable.

If lots of of the orders are edited, I can't just do context.SaveChanges() when a user hits "Save" and have EF Core only update the fields that have changed.

@inject OrderService _orderSerivce;

void DoTest()
{
    var orders =_orderSerivce.GetAllOrders(); // Gets 500 orders 

    Random r = new Random();

    // edit upto 20 orders. 
    for(int i = 0; i < 20; i++)
    {
       int rInt = r.Next(0, orders.Length-1);
       orders[rInt].CustomerName = "NameChanged " + i;
    }

    _orderSerivce.UpdateOrders(orders); // ?? What should this do
}

I'm not sure how the UpdateOrders function should work?

Should I just attach the orders and let it update all 500 orders. SaveChanges would have tracked what was edited and what is new and handle it all for me. E.g.

public async Task UpdateOrders(Order[] orders)
{
    // Use a new context instance to perform the updates
    using var ctx = _contextFactory.CreateDbContext();
    
    foreach (var order in orders)
    {
        // Attach each order to the context and mark it as modified
        ctx.Orders.Attach(order);
        ctx.Entry(order).State = EntityState.Modified;
    }

    // Save all changes to the database
    await ctx.SaveChangesAsync();
}

But with the disposed context, how do I now extract only the changes to update?

Upvotes: 1

Views: 118

Answers (0)

Related Questions