1

同様のタイトルの質問をすべて読みましたが、問題に対する答えが見つからなかったため、新しい質問を開きます。

2 つの 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;
      }
    }    
  }
}

1 つのテーブルのみを使用する場合に最適です。2 つのテーブルとそれらの間の外部キー関係を使用しようとすると、うまくいきません。たとえば、次の結合 tb1.int_id = tb2.tb1_id を使用して、tb1.my_id=5 のテーブル tb2 からすべてのレコードを取得しようとします。

List<tb2> lj = new Tb2DAO().GetByLambda(l => l.tb1.my_id == 5).ToList();

(Tb2DAO は、私の汎用リポジトリ クラスから継承されています。)

次の MySQL エラーがあります。

「MySql.Data.MySqlClient.MySqlException: この接続に関連付けられている開いている DataReader が既に存在し、最初に閉じる必要があります。」

これは、2 つのテーブル エンティティに共通ではない 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

メソッド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 に答える
1

この方法はよくわからない

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

EFコンテキストが知らない新しいオブジェクトセットを作成します。

Func<ObjectContext, ObjectResult<T>>派生クラスからベースに渡すことができます。(EF context. Fe から取得した ObjectResult を返す必要がありますcontext => context.Entities)。

于 2012-04-05T14:13:16.700 に答える