2012-04-05 7 views
1

Ich lese alle ähnlichen Titel Fragen, aber ich habe die Antwort auf mein Problem nicht gefunden, also öffne ich eine neue Frage:EF 4.1/Repository/UnitOfWork/MySQL: Es ist bereits ein offener DataReader mit dieser Verbindung verbunden, der zuerst geschlossen werden muss

ich habe zwei mySQL-Tabellen:

  • tb1 (INT_ID, Code, Beschreibung, ..., my_id);

  • tb2 (int_id, Code, Beschreibung, ..., tb1_id);

ich eine generische Repository DbContext und GetAll, GetById, GetByLambda, Einfügen, Aktualisieren und Löschen Methode zu verwalten.

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(); 
    } 

    ... 

    } 
} 

und die geerbte Klasse, die ich verwendet:

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; 
     } 
    }  
    } 
} 

Es funktioniert gut, wenn nur eine Tabelle. Wenn ich versuche, meine zwei Tabellen und die Fremdschlüsselbeziehung zwischen ihnen zu verwenden, funktioniert es nicht. Zum Beispiel versuche ich, alle Datensätze aus der Tabelle tb2 zu erhalten, wobei tb1.my_id = 5 mit dem folgenden Join tb1.int_id = tb2.tb1_id.

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

(Tb2DAO geerbt von meinem generic-Repository-Klasse.)

Ich habe folgende MySQL-Fehler:

„MySql.Data.MySqlClient.MySqlException: Es gibt bereits eine offene Datareader zugeordnet Diese Verbindung muss zuerst geschlossen werden. "

Ich denke, das kommt von meinem DbContext, die nicht meine beiden Tabellen Entitäten ist. Also versuchte ich das UnitOfWork Muster zu implementieren, um dieses Problem zu lösen, wie folgt aus:

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); 
    } 

    } 
} 

Und jetzt in meinem Code habe ich versucht, die Arbeitseinheit wie folgt zu verwenden:

UnitOfWork unitOfWork = new UnitOfWork(); 
List<tb2> tb2List = unitOfWork.tb2.GetByLambda(l => l.index_job.job_id == job_id).ToList(); 

Aber ich habe immer die gleiche Fehlermeldung:

"MySql.Data.MySqlClient.MySqlException: Es ist bereits ein offener DataReader mit dieser Verbindung verbunden, die zuerst geschlossen werden muss."

Gibt es etwas, was ich falsch mache? Können Sie mir bitte helfen ? Dieser Begriff von Repository und Einheit der Arbeit sind neu für mich und ich bin verwirrt, sonst lese ich viel darüber nachzudenken, kann es nicht der richtige sein ...

Ich auch zu versuchen, MultipleActiveResultSets = True zu meiner Verbindung hinzuzufügen aber es wird nicht erkannt.

viele danken allen & Grüßen, wst

Antwort

1

Ihre GetByLambda() Methode GetAll() ruft, die einen neuen Kontext ObjectContext.CreateObjectSet<T>() mit erstellt. Sie haben jetzt mehr als einen Kontext geöffnet. Ich würde empfehlen, die Standard-EF-Assoziationen und das Repository-Muster zu verwenden, dann können Sie dieses ganze Durcheinander vermeiden. Hier ist ein Link, der Ihnen beim Einstieg helfen kann - http://blogs.msdn.com/b/adonet/archive/2011/03/15/ef-4-1-code-first-walkthrough.aspx.

1

Ich bin nicht sicher über diese Methode

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

Es ist erstellen neue Objekt festgelegt, über die EF Zusammenhang nicht kennt.

Sie können versuchen, Func<ObjectContext, ObjectResult<T>> von abgeleiteten Klasse zu Basis zu übergeben. (Es sollte ObjectResult zurückgeben, die aus dem EF-Kontext stammen. ZB context => context.Entities).