Entity Framework Core - DataReader must be closed error when query two tables

0

I have an issue of using Entity Framework Core with MYSQL in my Asp.net Core 3.1 project. I got an error

An unhandled exception has occurred while executing the request. MySql.Data.MySqlClient.MySqlException (0x80004005): There is already an open DataReader associated with this Connection which must be closed first.

when querying two tables at the same time and then joining them. The detailed implementation is as follows - any suggestion is appreciated.

I try to avoid using ToList() after query in each table, thereby avoiding too much in memory operations.

In my project, I created an UnitOfWork with the following code.

public class UnitOfWork<T> : IUnitOfWork<T> where T : DbContext
{
    private readonly ILogger _logger;
    private readonly ThreadLocal<T> _localContext;
    public T DbContext => _localContext.Value;

    public UnitOfWork(ILoggerFactory loggerFactory, DbContextOptions dbContextOptions)
    {
        _logger = loggerFactory.CreateLogger<UnitOfWork<T>>();
        _localContext = new ThreadLocal<T>(() => (T)Activator.CreateInstance(typeof(T), dbContextOptions));
    }

    public int Commit()
    {
        return 0
    }

    void IUnitOfWork<T>.RegisterDeleted<TAggregateRoot>(TAggregateRoot entity)
    {
    }

    void IUnitOfWork<T>.RegisterModified<TAggregateRoot>(TAggregateRoot entity)
    {
    }

    void IUnitOfWork<T>.RegisterNew<TAggregateRoot>(TAggregateRoot entity)
    {
    }
}

After that I inject the IUnitOfWork<> as a singleton as

 builder.RegisterGeneric(typeof(UnitOfWork<>)).As(typeof(IUnitOfWork<>)).SingleInstance();

For each repository of entity that is going to be saved to database, IUnitOfWork<T> is injected through its constructor.

For example, I have table A and table B in database, and I have EntityA and EntityB as models that corresponding to these two tales. For each of them, I have RepositoryA and RepositoryB. In the example, EntityAs is DbSet<EntityA> EntityAs in DbContext.

public class RepositoryA: IRepository
{
    private IUnitOfWork _unitOfWork;

    public RepositoryA(IUnitOfWork<EntityA> unitOfWork)
    {
        _unitOfWork = unitOfWork
    }

    public IEnumerable<EntityA> List()
    {
        return _unitOfWork.DbContext.EntityAs;
    }
}

Now, When I try to use RepositoryA and RepositoryB together in a service class as

public class Service
{
    public Service(RepositoryA repoA, RepositoryB repoB)
    {
        let entityAs = repoA.List();
        let entityBs = repoB.List();

        let result = from entityA in entityAs
                     join entityB in eneityBs
                     on entityA.BId equals entityB.Id
                     where entityA.Id == 1
                     select entityB;
    }
}
c#
entity-framework-core
asked on Stack Overflow May 17, 2020 by Ben • edited May 17, 2020 by marc_s

1 Answer

0

I change

builder.RegisterGeneric(typeof(UnitOfWork<>)).As(typeof(IUnitOfWork<>)).SingleInstance();

to

builder.RegisterGeneric(typeof(UnitOfWork<>)).As(typeof(IUnitOfWork<>)).InstancePerDependency();

solved the problem

answered on Stack Overflow Oct 3, 2020 by Ben

User contributions licensed under CC BY-SA 3.0