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;
}
}
I change
builder.RegisterGeneric(typeof(UnitOfWork<>)).As(typeof(IUnitOfWork<>)).SingleInstance();
to
builder.RegisterGeneric(typeof(UnitOfWork<>)).As(typeof(IUnitOfWork<>)).InstancePerDependency();
solved the problem
User contributions licensed under CC BY-SA 3.0