1

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

我有两个mysql表:

  • tb1 (int_id, 代码, 描述, ..., my_id);

  • tb2 (int_id, 代码, 描述, ..., 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;
      }
    }    
  }
}

仅使用一张桌子时效果很好。当我尝试使用我的两个表和它们之间的外键关系时,它不起作用。例如,我尝试使用以下连接 tb1.int_id = tb2.tb1_id 从表 tb2 中获取所有记录,其中 tb1.my_id=5。

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

4

2 回答 2

1

我不确定这种方法

public virtual IQueryable<T> GetAll()
{
    return ObjectContext.CreateObjectSet<T>();
}

它创建了关于 EF 上下文不知道的新对象集。

您可以尝试Func<ObjectContext, ObjectResult<T>>从派生类传递到基类。(它应该返回从 EF 上下文中获取的 ObjectResult。 Fe context => context.Entities)。

于 2012-04-05T14:13:16.700 回答
1

您的GetByLambda()方法正在调用GetAll(),它使用ObjectContext.CreateObjectSet<T>(). 因此,您现在打开了多个上下文。我建议使用标准的 EF 关联和存储库模式,这样你就可以避免这整个混乱。这是一个可以帮助您入门的链接 - http://blogs.msdn.com/b/adonet/archive/2011/03/15/ef-4-1-code-first-walkthrough.aspx

于 2012-04-05T14:09:06.847 回答