Frage

Ich baue eine 4 geschichtete ASP.Net Web-Anwendung. Die Schichten sind:

  1. Data Layer
  2. Entity-Layer
  3. Business Layer
  4. UI-Layer

Die Entität Schicht hat meine Daten Modellklassen und wird von meiner Entität Datenmodell (edmx-Datei) in der Datalayer unter Verwendung von T4-Vorlagen (POCO) gebaut. Die Einheit Schicht ist in allen anderen Schichten verwiesen wird.

Meine Datenschicht hat eine Klasse namens SourceKeyRepository, die eine Funktion hat, etwa so:

public IEnumerable<SourceKey> Get(SourceKey sk)
{
    using (dmc = new DataModelContainer())
    {
        var query = from SourceKey in dmc.SourceKeys
                    select SourceKey;

        if (sk.sourceKey1 != null)
        {
            query = from SourceKey in query
                    where SourceKey.sourceKey1 == sk.sourceKey1
                    select SourceKey;
        }

        return query;
    }
}

Lazy Loading ist deaktiviert, da ich meine Fragen nicht in anderen Schichten dieser Anwendung ausgeführt werden soll. Ich erhalte die folgende Fehlermeldung beim Versuch, die Informationen in der UI-Ebene zuzugreifen:

Die Object Instanz wurde angeordnet ist und nicht mehr verwendet werden kann, um Operationen, die eine Verbindung erforderlich ist.

Ich bin sicher, dass dies, weil mein DataModelContainer „dmc“ angeordnet war. Wie kann ich dieses IEnumerable-Objekt aus meiner Datenschicht zurückkehren, so dass sie nicht auf dem Object angewiesen ist, sondern einzig und allein auf dem Datenmodell?

Gibt es eine Möglichkeit verzögertes Laden zu begrenzen, um nur in der Datenschicht auftreten?

War es hilfreich?

Lösung

query ist faul ausgewertet, so dass die Daten nicht aus der Datenbank retreived wird, bis Sie sie aufzuzählen.

Wenn Sie das tun:

return query.ToList();

Sie erhalten die Abfrage erzwingen ausgeführt werden und das Problem zu vermeiden.

Sie erhalten die Fehlermeldung, weil, wenn der Anrufer die Sammlung aufzählt, die Object (dmc) ist bereits angeordnet dank Ihrer using Klausel (was gut ist - dispose Datenbank bezogenen Ressourcen früh)

Bearbeiten

In der ursprünglichen Nachricht verwendet ich AsEnumerable(), die ich dachte, war richtig - bis ich vor kurzem versucht, mich in dieser Situation genau zu verwenden. AsEnumerable() macht nur einen Compiler-Typ-Konvertierung - es nicht aufzuzählen. Um die Abfrage zu erzwingen aufgezählt werden, hat in einem List oder anderer Sammlung gespeichert werden.

Andere Tipps

Sie können eine Methode auf dem query Objekt aufrufen, zum Beispiel

return query.AsEnumerable();

Das sollten Sie sicherstellen, dass die Abfrage ausführen, also dafür, dass Sie den Objektkontext nicht brauchen später.

Verwenden Sie keine

return query.AsEnumerable();

Verwendung

return query.ToArray();

vor Ihrem Kontext zu entsorgen.

Rückkehr AsEnumerable nicht die foreach ausführen, bis das Objekt referenziert wird. Umwandeln sorgt er auf ein Array der foreach wird ausgeführt, bevor das Objekt angeordnet ist. Sie können Ihren Kontext in einem using-Block (etwas, das man tun soll) dann setzen.

Meiner Meinung nach, hat dieses Szenario keine Relevanz mit AsEnumerable () oder AsQueryable (). Versuchen Sie dies;

 public IEnumerable<SourceKey> Get(SourceKey sk, DataModelContainer dmc) {    

    var query = from SourceKey in dmc.SourceKeys
                select SourceKey;

    if (sk.sourceKey1 != null)
    {
        query = from SourceKey in query
                where SourceKey.sourceKey1 == sk.sourceKey1
                select SourceKey;
    }

    return query;

}

Und Sie müssen diese Eigenschaft erhalten mit

using (dmc = new DataModelContainer()) {
 // GET
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top