question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Connection is Busy

See original GitHub issue

I’ve got the following problem:

I’m using NPGSQL for the Connection to the Database. Furthermore I’m using Entity Framework Core.

This is how my Context looks like:

using System.IO;
using DatabaseLibrary.Models.Discount;
using DatabaseLibrary.Models.Gender;
using DatabaseLibrary.Models.Ranks;
using DatabaseLibrary.Models.Employee;
using DatabaseLibrary.Models.Items;
using DatabaseLibrary.Models.Settings;
using DatabaseLibrary.Models.Transaction;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;

namespace DatabaseLibrary
{
    // ReSharper disable once InconsistentNaming
    public class PGSQLConnectionManager : DbContext
    {
        //Variables
        private IConfiguration Configuration { get; }

        //public PGSQLConnectionManager(DbContextOptions<PGSQLConnectionManager> options) : base(options)
        //{
        //    Configuration = (new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.Development.json").Build());
        //}

        public PGSQLConnectionManager()
        {
            Configuration = (new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.Development.json").Build());
        }

        public PGSQLConnectionManager(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        //Database
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
            => optionsBuilder.UseNpgsql(
                Configuration["ConnectionStrings:PGSQLConnectionManager"]
            );
        
        //Model Sets
        public DbSet<Gender> Gender { get; set; }
        public DbSet<Gender2Employee> Gender2Employee { get; set; }
        public DbSet<EmployeeRank> EmployeeRank { get; set; }
        public DbSet<Employee> Employee { get; set; }
        public DbSet<Item> Item { get; set; }
        public DbSet<ItemType> ItemType { get; set; }
        public DbSet<ItemType2Item> ItemType2Items { get; set; }
        public DbSet<EmployeeRank2Employee> EmployeeRank2Employees { get; set; }
        public DbSet<Transaction> Transactions { get; set; }
        public DbSet<Transaction2Items> Transaction2Items { get; set; }
        public DbSet<TransactionNonItem> TransactionNonItem { get; set; }
        public DbSet<TaxSettings> TaxSettings { get; set; }
        public DbSet<Discount> Discount { get; set; }
        public DbSet<Transaction2Discount> Transaction2Discount { get; set; }
        public DbSet<EmployeeRank2AspRole> EmployeeRank2AspRoles { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Gender>().ToTable("Gender");
            modelBuilder.Entity<Gender2Employee>().ToTable("Gender2Employee");
            modelBuilder.Entity<EmployeeRank>().ToTable("EmployeeRank");
            modelBuilder.Entity<Employee>().ToTable("Employee");
            modelBuilder.Entity<EmployeeRank2Employee>().ToTable("EmployeeRank2Employee");
            modelBuilder.Entity<Item>().ToTable("Item");
            modelBuilder.Entity<ItemType>().ToTable("ItemType");
            modelBuilder.Entity<ItemType2Item>().ToTable("ItemType2Item");
            modelBuilder.Entity<Transaction>().ToTable("Transaction");
            modelBuilder.Entity<Transaction2Items>().ToTable("Transaction2Items");
            modelBuilder.Entity<TransactionNonItem>().ToTable("TransactionNonItem");
            modelBuilder.Entity<TaxSettings>().ToTable("TaxSettings");
            modelBuilder.Entity<Discount>().ToTable("Discount");
            modelBuilder.Entity<Transaction2Discount>().ToTable("Transaction2Discount");
            modelBuilder.Entity<EmployeeRank2AspRole>().ToTable("EmployeeRank2AspRole");

            /*
             * Primary Key auto increment
             */
            modelBuilder.Entity<Gender>()
                .Property(g => g.GenderId)
                .UseIdentityColumn();
            modelBuilder.Entity<Gender2Employee>()
                .Property(g => g.Gender2EmployeeId)
                .UseIdentityColumn();
            modelBuilder.Entity<Item>()
                .Property(i => i.ItemId)
                .UseIdentityColumn();
            modelBuilder.Entity<ItemType>()
                .Property(it => it.ItemTypeId)
                .UseIdentityColumn();
            modelBuilder.Entity<ItemType2Item>()
                .Property(iti => iti.ItemType2ItemId)
                .UseIdentityColumn();
            modelBuilder.Entity<EmployeeRank>()
                .Property(er => er.EmployeeRankId)
                .UseIdentityColumn();
            modelBuilder.Entity<EmployeeRank2Employee>()
                .Property(ere => ere.EmployeeRank2EmployeeId)
                .UseIdentityColumn();
            modelBuilder.Entity<Transaction>()
                .Property(t => t.TransactionId)
                .UseIdentityColumn();
            modelBuilder.Entity<Transaction2Items>()
                .Property(ti => ti.Transaction2ItemsId)
                .UseIdentityColumn();
            modelBuilder.Entity<TransactionNonItem>()
                .Property(tni => tni.TransactionId)
                .UseIdentityColumn();
            modelBuilder.Entity<TaxSettings>()
                .Property(ts => ts.TaxSettingsId)
                .UseIdentityColumn();
            modelBuilder.Entity<Discount>()
                .Property(d => d.DiscountId)
                .UseIdentityColumn();
            modelBuilder.Entity<Transaction2Discount>()
                .Property(t2d => t2d.Transaction2DiscountId)
                .UseIdentityColumn();
            modelBuilder.Entity<EmployeeRank2AspRole>()
                .Property(e2a => e2a.EmployeeRank2AspRoleId)
                .UseIdentityColumn();

            /*
             * Relations
             */
            //Gender
            modelBuilder.Entity<Gender2Employee>()
                .HasOne<Employee>()
                .WithMany()
                .HasForeignKey(e => e.EmployeeId)
                .HasPrincipalKey(e => e.EmployeeId);
            modelBuilder.Entity<Gender2Employee>()
                .HasOne<Gender>()
                .WithMany()
                .HasForeignKey(g => g.GenderId)
                .HasPrincipalKey(g => g.GenderId);

            //item
            modelBuilder.Entity<ItemType2Item>()
                .HasOne<Item>()
                .WithMany()
                .HasForeignKey(i => i.ItemId)
                .HasPrincipalKey(i => i.ItemId);
            modelBuilder.Entity<ItemType2Item>()
                .HasOne<ItemType>()
                .WithMany()
                .HasForeignKey(i => i.ItemTypeId)
                .HasPrincipalKey(i => i.ItemTypeId);
            
            //transaction
            //transaction2items
            modelBuilder.Entity<Transaction2Items>()
                .HasOne<Transaction>()
                .WithMany()
                .HasForeignKey(t => t.TransactionId)
                .HasPrincipalKey(t => t.TransactionId);
            modelBuilder.Entity<Transaction2Items>()
                .HasOne<Item>()
                .WithMany()
                .HasForeignKey(i => i.ItemId)
                .HasPrincipalKey(i => i.ItemId);
            //transaction2discount
            modelBuilder.Entity<Transaction2Discount>()
                .HasOne<Transaction>()
                .WithMany()
                .HasForeignKey(t => t.TransactionId)
                .HasPrincipalKey(t => t.TransactionId);
            modelBuilder.Entity<Transaction2Discount>()
                .HasOne<Discount>()
                .WithMany()
                .HasForeignKey(d => d.DiscountId)
                .HasPrincipalKey(d => d.DiscountId);
            
            //employeerank2asproleid
            modelBuilder.Entity<EmployeeRank2AspRole>()
                .HasOne<EmployeeRank>()
                .WithMany()
                .HasForeignKey(er => er.EmployeeRankId)
                .HasPrincipalKey(er => er.EmployeeRankId);
        }
    }
}

In my Startup.cs I’m adding the context to the dependency injection like this:

//Database initialization
            services.AddDbContext<PGSQLConnectionManager>(options => 
             options.UseNpgsql(Configuration.GetConnectionString("PGSQLConnectionManager")));
            services.AddDatabaseDeveloperPageExceptionFilter();

Now since my latest additional query I was using the Context like this:

In any .razor file I’m injecting the PGSQLConnectionManager:

@inject PGSQLConnectionManager Context

And later on in the .razor file in the @code part, I use the injected Context like this:

GetEmployee getAllEmployees = new GetEmployee(Context);

And every Class that needs a database connection is getting initialized like this:

 public class GetEmployee
    {
        //Variables
        private readonly PGSQLConnectionManager _connectionManager;

        public GetEmployee(PGSQLConnectionManager context)
        {
            _connectionManager = context;
        }

        public List<Employee> GetAllEmployees()
        {
            try
            {
                //query all employees
                List<Employee> allEmployees = _connectionManager.Employee.AsQueryable().ToList();
                return allEmployees;
            }
            catch (Exception e)
            {
                #I know this is bad, but reporting is to come
                return null;
            }
        }
    }

And now, that I’ve done this like, >20 times I get an error: Connection is Busy

I tried using a static class and reference the PGSQLConnectionManager in there once, but then everytime I try to get the Context I get an error, that the Object has been disposed??? and can’t get accessed anymore. As far as I know, objects do not get disposed if they are in a static class. I couldn’t find where the database gets disposed in the static class thing.

So far, I think I’m using EntityFramework or the NPGSQL wrong. But I cannot find a good example, that represents my case.

Thanks ahead for any help

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
Karmageddoniumcommented, Jan 19, 2022

Yeah, it explains everything, thanks. I decided to write here this example for further watchers of this thread, coz the topicstarter havent written anything about his workaround or solution

0reactions
rojicommented, Jan 19, 2022

@Karmageddonium this is superficially similar to the concurrent collection modification error, but things are actually simpler. A single DbContext has a single database connection, and the foreach is already using that connection for streaming query results back. Therefore SaveChanges cannot be invoked, since the connection is already busy…

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why only some users get the error: "Connection is busy ...
The "Connection is busy with results for another command" error means that there are at least two queries that use the same connection....
Read more >
Connection is busy with results for another command ...
Happens when you have an active process (DataReader) and you try to run another process (SELECT). Example: /* ...
Read more >
"Connection is busy with results for another command" error
"Connection is busy with results for another command" error in a specific scenario when using SQL Server ODBC 17 driver. Applies to
Read more >
Common Error: Connection is busy with results for...
It seems the table mentioned is not updated and needs to be reloaded when this happens. Thanks. Martin.
Read more >
[Microsoft][ODBC Driver for SQL Server]Connection is busy ...
My internet searches have led me to believe this is due to Multiple Active Result Sets not being enabled. I looked in the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found