EF 4.1/Reportory/UnitOfWork/MySQL:已经有一个打开的DataReader与此连接关联,必
本文关键字:DataReader 连接 关联 有一个 Reportory UnitOfWork MySQL EF | 更新日期: 2023-09-27 18:30:12
我读了所有类似标题的问题,但我没有找到问题的答案,所以我打开了一个新问题:
我有两个mysql表:
-
tb1(int_id,code,description,…,my_id);
-
tb2(int_id,code,description,…,tb1_id);
我创建了一个通用存储库来管理DbContext和GetAll、GetById、GetByLambda、Insert、Update和Delete方法。
namespace Model.DataAccessLayer
{
public class Repository<T> : IRepository<T> where T : EntityObject, IEntity
{
protected DbContext dbContext = null;
public virtual DbContext DbContext
{
get { return dbContext; }
set { dbContext = value; }
}
public ObjectContext ObjectContext
{
get { return ((IObjectContextAdapter)DbContext).ObjectContext; }
}
public void Dispose()
{
ObjectContext.Dispose();
System.GC.SuppressFinalize(this);
}
public virtual IQueryable<T> GetAll()
{
return ObjectContext.CreateObjectSet<T>();
}
public virtual IEnumerable<T> GetByLambda(Func<T, bool> p)
{
return GetAll().Where(p);
}
public virtual void Save()
{
DbContext.SaveChanges();
}
...
}
}
以及我使用的继承类:
namespace Model.DataAccessLayer
{
public class RepositoryP<T> : Repository<T> where T : EntityObject, IEntity
{
public myEntities MyContext
{
get { return (myEntities)ObjectContext; }
//set { ObjectContext = value; }
}
public override DbContext DbContext
{
get
{
if (dbContext == null)
{
dbContext = new DbContext("myEntities");
}
return dbContext;
}
set
{
base.DbContext = value;
}
}
}
}
只使用一张桌子时效果很好。当我尝试使用我的两个表以及它们之间的外键关系时,它不起作用。例如,我尝试从表tb2中获取所有记录,其中tb1.my_id=5,并使用以下联接tb1.int_id=tb2.tb1_id.
List<tb2> lj = new Tb2DAO().GetByLambda(l => l.tb1.my_id == 5).ToList();
(Tb2DAO继承自我的通用存储库类。)
我有以下MySQL错误:
"MySql.Data.MySqlClient.MySqlException:已经有一个打开的DataReader与此连接关联,必须首先关闭。"
我认为这来自于我的DbContext,它对我的两个表实体来说并不常见。所以我尝试实现UnitOfWork模式来解决这个问题,比如:
namespace Model.DataAccessLayer
{
public class UnitOfWork : IDisposable
{
private DbContext dbContextUnit = null; //= new DbContext();
private Tb1DAO tb1DAO;
private Tb2DAO tb2DAO;
public Tb1DAO tb1
{
get
{
if (this.tb1DAO == null)
{
if (dbContextUnit != null)
{
this.tb1DAO = new Tb1DAO { DbContext = dbContextUnit };
}
else
{
this.tb1DAO = new Tb1DAO();
dbContextUnit = this.tb1DAO.DbContext;
}
}
return tb1DAO;
}
}
public Tb2DAO tb2
{
get
{
if (this.tb2DAO == null)
{
if (dbContextUnit != null)
{
this.tb2DAO = new Tb2DAO { DbContext = dbContextUnit };
}
else
{
this.tb2DAO = new Tb2DAO();
dbContextUnit = this.tb2DAO.DbContext;
}
}
return tb2DAO;
}
}
public void Save()
{
dbContextUnit.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
dbContextUnit.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
}
现在,在我的代码中,我尝试使用这样的工作单元:
UnitOfWork unitOfWork = new UnitOfWork();
List<tb2> tb2List = unitOfWork.tb2.GetByLambda(l => l.index_job.job_id == job_id).ToList();
但我总是收到同样的错误信息:
"MySql.Data.MySqlClient.MySqlException:已经有一个打开的DataReader与此连接关联,必须首先关闭。"
我做错什么了吗?你能帮我吗?存储库和工作单元的概念对我来说是新的我很困惑,否则我读了很多关于它的思考可能不是正确的。。。
我还试图将MultipleActiveResultSets=true添加到我的连接中,但它没有被识别。
非常感谢所有&当做wst
GetByLambda()
方法正在调用GetAll()
,该方法使用ObjectContext.CreateObjectSet<T>()
创建新上下文。因此,您现在打开了不止一个上下文。我建议使用标准的EF关联和存储库模式,这样就可以避免整个混乱。这里有一个链接,可以帮助你开始-http://blogs.msdn.com/b/adonet/archive/2011/03/15/ef-4-1-code-first-walkthrough.aspx.
我不确定这个方法
public virtual IQueryable<T> GetAll()
{
return ObjectContext.CreateObjectSet<T>();
}
它是创建EF上下文不知道的新对象集。
您可以尝试将Func<ObjectContext, ObjectResult<T>>
从派生类传递到基类。(它应该返回从EF上下文中得到的ObjectResult。例如context => context.Entities
)。