C# EF 4.1/Repository/UnitOfWork/MySQL:已经有一个与此连接关联的打开的DataReader,必须先关闭它

C# EF 4.1/Repository/UnitOfWork/MySQL:已经有一个与此连接关联的打开的DataReader,必须先关闭它,c#,mysql,entity-framework-4.1,repository,unit-of-work,C#,Mysql,Entity Framework 4.1,Repository,Unit Of Work,我阅读了所有类似的标题问题,但我没有找到问题的答案,因此我打开了一个新问题: 我有两个mysql表: tb1(内部id、代码、描述、…、我的id) tb2(内部id、代码、描述等,tb1\U id) 我创建了一个通用存储库来管理DbContext和GetAll、GetById、GetByLambda、Insert、Update和Delete方法 namespace Model.DataAccessLayer { 公共类存储库:IRepository,其中T:EntityObject,Enti

我阅读了所有类似的标题问题,但我没有找到问题的答案,因此我打开了一个新问题:

我有两个mysql表:

  • tb1(内部id、代码、描述、…、我的id)

  • tb2(内部id、代码、描述等,tb1\U id)

我创建了一个通用存储库来管理DbContext和GetAll、GetById、GetByLambda、Insert、Update和Delete方法

namespace Model.DataAccessLayer
{
公共类存储库:IRepository,其中T:EntityObject,EntityObject
{
受保护的DbContext-DbContext=null;
公共虚拟DbContext DbContext
{
获取{return dbContext;}
设置{dbContext=value;}
}
公共对象上下文对象上下文
{
获取{return((IObjectContextAdapter)DbContext).ObjectContext;}
}
公共空间处置()
{
Dispose();
System.GC.SuppressFinalize(本);
}
公共虚拟IQueryable GetAll()
{
返回ObjectContext.CreateObjectSet();
}
公共虚拟IEnumerable GetByLambda(Func p)
{
返回GetAll(),其中(p);
}
公共虚拟void Save()
{
DbContext.SaveChanges();
}
...
}
}
以及我使用的继承类:

namespace Model.DataAccessLayer
{
公共类RepositoryP:存储库,其中T:EntityObject,EntityObject
{
公共myEntities MyContext
{
获取{return(myEntities)ObjectContext;}
//设置{ObjectContext=value;}
}
公共覆盖DbContext DbContext
{
得到
{
if(dbContext==null)
{
dbContext=新的dbContext(“myEntities”);
}
返回dbContext;
}
设置
{
base.DbContext=值;
}
}    
}
}
当只使用一张桌子时,效果非常好。 当我尝试使用我的两个表以及它们之间的外键关系时,它不起作用。 例如,我尝试从表tb2中获取所有记录,其中tb1.my_id=5,具有以下join tb1.int_id=tb2.tb1_id

List lj=new Tb2DAO().GetByLambda(l=>l.tb1.my_id==5.ToList();
(Tb2DAO继承自我的通用存储库类。)

我有以下MySQL错误:

“MySql.Data.MySqlClient.MySqlException:已经有一个与此连接关联的打开的DataReader,必须先关闭它。”

我认为这来自于我的DbContext,这对于我的两个表实体来说并不常见。 所以我尝试实现UnitOfWork模式来解决这个问题,如下所示:

namespace Model.DataAccessLayer
{
公共类UnitOfWork:IDisposable
{
私有DbContext dbContextUnit=null;//=new DbContext();
私人Tb1DAO Tb1DAO;
私人Tb2DAO Tb2DAO;
公共tb1 DAO tb1
{
得到
{
if(this.tb1DAO==null)
{
if(dbContextUnit!=null)
{
this.tb1DAO=newtb1dao{DbContext=dbContextUnit};
}
其他的
{
this.tb1DAO=新的tb1DAO();
dbContextUnit=this.tb1DAO.DbContext;
}
}
返回tb1DAO;
}
}
公共Tb2DAO tb2
{
得到
{
if(this.tb2DAO==null)
{
if(dbContextUnit!=null)
{
this.tb2DAO=newtb2dao{DbContext=dbContextUnit};
}
其他的
{
this.tb2DAO=新的tb2DAO();
dbContextUnit=this.tb2DAO.DbContext;
}
}
返回tb2DAO;
}
}
公共作废保存()
{
dbContextUnit.SaveChanges();
}
私有布尔=假;
受保护的虚拟void Dispose(bool disposing)
{
如果(!this.disposed)
{
如果(处置)
{
dbContextUnit.Dispose();
}
}
这是真的;
}
公共空间处置()
{
处置(真实);
总干事(本);
}
}
}
现在在我的代码中,我尝试使用如下工作单元:

UnitOfWork UnitOfWork=新建UnitOfWork();
List 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()
创建一个新上下文。因此,您现在打开了多个上下文。我建议使用标准的EF关联和存储库模式,这样您就可以避免整个混乱。这里有一个链接可以帮助您入门-。

我不确定这个方法

public virtual IQueryable<T> GetAll()
{
    return ObjectContext.CreateObjectSet<T>();
}
公共虚拟IQueryable GetAll() { 返回ObjectContext.CreateObjectSet(); } 创建新建对象集是EF上下文不知道的

您可以尝试将
Func
从派生类传递到基类。(它应该返回从EF context.F.e.
context=>context.Entities
获取的ObjectResult)