2
votes

Using .NET Core 2.1, NPGSQL, Entity Framework and Linux.

From Startups.cs' Configure function, I am calling a function in a dependency injected class that in turn calls another dependency injected class which accesses the DB using Entity Framework + NPGSQL.

Configure Services:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddEntityFrameworkNpgsql()
        .AddDbContext<MMContext>(options => options.UseNpgsql($"Host='localhost'; Port=1234;Database='mydb';Username='test';Password='test'"))
        .BuildServiceProvider();
        services.AddTransient<IMusicManager, MusicManager>();
        services.AddTransient<IMusicRepo, MusicRepo>();

      services.AddMvc()
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

Configure function:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseMvc();

        using (var scope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
        {
            var mm = scope.ServiceProvider.GetRequiredService<IMusicManager>();
            mm.DoSomeDBStartupStuff();
        }
    }

IMusicManager

Implementation looks like this:

    private readonly IMusicRepo _musicStoreRepo;
    public MusicManager(IMusicRepo musicStoreRep)
    {
        _musicStoreRepo = musicStoreRepo;
    }

    public void DoSomeDBStartupStuff()
    {
        _musicStoreRepo.InsertSampleStuff();
        _musicStoreRepo.CheckThisAndCheckThat();
    }

IMusicRepo

Implementation looks like this:

    private readonly MMContext _context;
    public MusicRepo(MMContext context)
    {
        _context = context;
    }

    public void InsertSampleStuff()
    {
        _context.Music.AddAsync(new music("abc"));
        _context.Music.AddAsync(new music("123"));
        _context.SaveChangesAsync();
    }

MMContext

This is implemented as so:

public class MMContext : DbContext
{
    public MMContext(DbContextOptions<MMContext> options) : base(options) {}
    ... OnModelCreating etc...
}

I get this exception on firing it up:

Application startup exception: System.InvalidOperationException: Reset() called on connector with state Executing at Npgsql.NpgsqlConnector.Reset() at Npgsql.ConnectorPool.Release(NpgsqlConnector connector) at Npgsql.NpgsqlConnection.Close(Boolean wasBroken) at Npgsql.NpgsqlConnection.Dispose(Boolean disposing) at System.ComponentModel.Component.Dispose() at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Dispose() at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.Dispose() at Microsoft.EntityFrameworkCore.DbContext.Dispose() at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.Dispose() at MM.Startup.Configure(IApplicationBuilder app, IHostingEnvironment env) in \Startup.cs:line 122 --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.Configure(IApplicationBuilder app) at Microsoft.AspNetCore.HostFilteringStartupFilter.<>c__DisplayClass0_0.b__0(IApplicationBuilder app) at Microsoft.AspNetCore.Hosting.Internal.AutoRequestServicesStartupFilter.<>c__DisplayClass0_0.b__0(IApplicationBuilder builder) at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()

I am not sure what is causing the issue. Possibly the way I am using Dependency Injection and the way I am using the scope? Help appreciated.

1
Could you please share the issue/exception details? And where and how is your DbContext configured? - rudolfdobias
It doesn't seem like your registering Entity Framework anywhere in your code... Take a look at docs.microsoft.com/en-us/ef/core/get-started/aspnetcore/… - Shay Rojansky
sorry! I will add vital information as soon as I can - PKCS12
@Rollhard Without a minimal reproducible example that clarifies your specific problem or additional details to highlight exactly what you need, it’s hard to tell exactly what you're asking. - Nkosi
Hi, I've added additional info - apologies, but I was trying keep things simple and exclude too much noise. - PKCS12

1 Answers

1
votes

Noticing async calls not being awaited in a void function.

public void InsertSampleStuff()
{
    _context.Music.AddAsync(new music("abc"));
    _context.Music.AddAsync(new music("123"));
    _context.SaveChangesAsync();
}

This could cause threading issues with the DbContext when you try to save those changes.

Either make the function async and await those calls properly or use the synchronous API

public void InsertSampleStuff() {
    _context.Music.Add(new music("abc"));
    _context.Music.Add(new music("123"));
    _context.SaveChanges();
}

If going the asynchronous route then consider moving that setup code into a hosted service and properly awaiting it there

Reference Reference Background tasks with hosted services in ASP.NET Core