Search code examples
c#asp.net-coreentity-framework-coresignalrc#-8.0

Clean database on application startup


I've adapted an approach of mapping signalr connections to users to my aspnet core 3.0 app. The approach I'm referring to is outlined in Mapping SignalR Users to Connections, section Permanent, external storage. I know that this article was written for a different version of Asp.Net but it came in handy.

This is the code of the Hub:

public class SomeHub : Hub
{
    private readonly UserManager _userManager;
    private readonly AppDbContext _dbContext;

    protected BaseHub(UserManager userManager, AppDbContext dbContext)
    {
        _userManager = userManager;
        _dbContext = dbContext;
    }

    public override async Task OnConnectedAsync()
    {
        var user = await _userManager.GetMe();
        user.Connections.Add(new Connection { ConnectionId = Context.ConnectionId });
        await _dbContext.SaveChangesAsync();
        await base.OnConnectedAsync();
    }

    public override async Task OnDisconnectedAsync(Exception ex)
    {
        var user = await _userManager.GetMe();
        if (await _dbContext.Connections.FindAsync(Context.ConnectionId) is {} connection)
        {
            user.Connections.Remove(connection);
            await _dbContext.SaveChangesAsync();
        }

        await base.OnDisconnectedAsync(ex);
    }
}

Question

If I teardown my application, Connection database entries will remain in my database, because the OnDisconnectedAsync method was not called.

Is there a possibility to remove those entries once the application starts?


Solution

  • I needed to add the following code inside the Configure method of the Startup class after calling AddDbContext:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<AppDbContext>([...]);
    
        using (var serviceProvider = services.BuildServiceProvider())
        using (var serviceScope = serviceProvider.CreateScope())
        using (var context = scope.ServiceProvider.GetService<AppDbContext>())
        {
            context.Connections.RemoveRange(context.Connections);
            context.SaveChanges();
        }
        [...]
    }