Frage

Was ist die beste Praxis in Bezug auf meine Datacontext für eine einfachen Zugang in meinen erweiterten LinqToSql Klassen einrichten?

Zum Beispiel, ich habe eine „User“ Einheit in meiner dbml und ich mag diese Klasse Methoden hinzufügen wie folgt:

Partial Public Class User

    Public Function GetUser(ByVal UserID as Integer) as User
         'Do Work
    End Function

End Class

Um meine Datacontext zugreifen Ich würde es wie so innerhalb der Methode deklarieren:

Partial Public Class User

    Public Function GetUser(ByVal UserID as Integer) as User
         Dim dc as New MyDataContext()
         Return (From u in dc.Users Where u.ID = UserID).Single()
    End Function

End Class

Ich möchte nicht, dass für jede einzelne Methode zu tun haben. Normalerweise (wenn ich nicht die LinqToSql dbml Klassen erstreckten, wurden) konnte ich dies nur tun:

Partial Public Class User
    Private dc as MyDataContext

    Public Sub New()
         dc = new MyDataContext()
    End Sub

    Public Function GetUser(ByVal UserID as Integer) as User
         Return (From u in dc.Users Where u.ID = UserID).Single()
    End Function

    Public Function GetAllUsers() as IEnumerable(Of User)
         Return From u in dc.Users
    End Function

    'etc...

End Class

Das würde mir erlauben, die Datacontext für jede Methode zuzugreifen, ohne dass es jedes Mal neu anmelden zu müssen. Aber natürlich kann man das nicht tun, weil die dbml bereits einen Konstruktor hat. Und das Hinzufügen von Code in das dbml immer überschrieben wird, wenn etwas jemals ändert.

Wer noch keine gute Ideen, wie mir einige überschüssige Code hier sparen?

TIA!

War es hilfreich?

Lösung

Stellen Sie zunächst sicher, dass Sie Ihre Datacontext sind entsorgen, wenn Sie fertig sind! Er kann ein schwerer kleiner Bastard sein ( Bearbeiten nicht schwer zu instanziieren, aber schwer um zu halten, wenn Sie es verwenden halten, ohne Entsorgung); Sie nicht alt Datacontexts wollen um im Speicher hängen.

Zweitens die Datacontext sollte eine einzelne logische Transaktion darzustellen . Z.B. Sie sollten ein neues jedes Mal, wenn eine neue Transaktion, starten wollen erstellen und es loswerden, wenn , die Transaktion abgeschlossen ist. Also für Ihre Zwecke, dh wahrscheinlich der Umfang der GetUser Methode. Wenn Sie eine Reihe von DB Anrufen, die als Gruppe vorgenommen werden müssen, sollten sie alle verwenden die gleichen DC, bevor es loszuwerden.

Andere Tipps

Wie Rex M sagte , die Datacontext sollte für jede logische Transaktion instantiiert, verwendet und entsorgt werden. Muster wie diese sind manchmal eine „Arbeitseinheit“ genannt.

Die gängigste Methode (die ich kenne), dies zu tun ist Ihr Datacontext in einem mit Block zu instanziiert. Ich habe nicht VB in einer Weile benutzt, aber es soll in etwa so aussehen:

Using dc As New MyDataContext()
   user = (From u in dc.Users Where u.ID = UserID).Single()
End Using

Dies verstärkt nicht nur die aussehen einer Transaktion / Arbeitseinheit (durch die physische Form des Codes), aber es wird sichergestellt, Dispose () auf Ihrem Datacontext, wenn die Blockenden aufrufen.

Siehe dieser MSDN-Seite :

  

Im Allgemeinen ist eine Datacontext-Instanz ist ausgelegt für eine „Einheit zum letzten von   Arbeit“aber Ihre Anwendung definiert   dieser Begriff. Ein Datacontext ist   leicht und ist nicht teuer   erstellen. Ein typisches LINQ to SQL   Anwendung erstellt Datacontext   Instanzen bei Methode Umfang oder als   Mitglied der kurzlebigen Klassen,   stellt einen logischen Satz verwandter   Datenbankoperationen.

Ich denke, vielleicht das eigentliche Problem ist, dass User ist wahrscheinlich nicht der richtige Ort für eine Instanz Mitglied Anruf GetUser.

Es gibt ein paar verschiedene Möglichkeiten, wie Sie zu diesem gehen könnten, die gute Praxis wäre, glaube ich. Zunächst könnten Sie ein Repository-Muster verwenden, in dem Sie das Repository für ein Objekt abzufragen, ist es aus mit der Datenbank geht, ruft das Objekt - vielleicht ist es aus dem Datenkontext Abnehmen oder den Datenkontext um über die Umsetzung des Repository in Abhängigkeit zu halten - und gibt es Ihnen. Die Factory-Methoden für Ihre Objekte würden auf dem Repository, nicht die Entitäten selbst. Sie würden vermutlich Reflexion und Generika verwenden, um die Anzahl der Methoden, die Sie Ihren Code DRY umsetzen müssen, minimieren und zu halten.

Der andere Weg, und die Art und Weise LINQtoSQL gedacht war nativ IMHO verwendet werden soll, ist es, den Datenkontext für jeden Satz von Datenbankoperationen zu erstellen, die Sie ausführen möchten. Dabei wird die Erstellung des Datenkontextes erfolgt außerhalb des Unternehmens als auch, in der Regel in der Klasse, die die Entitäten verwendet, nicht in der Datenschicht alle auf. Sie könnten auch Methoden zum Datenkontext - fügen Sie Ihre aktuellen Daten Kontext abstrakt machen und daraus erben - mit Reflexion wieder, einige der gemeinsamen Abruffunktionen auszuführen, so dass Sie müssen sie nicht wiederholen. Sie würden wahrscheinlich eine Datenbank Muster wie ActiveRecords verwenden müssen, wo die ID-Spalten immer die gleichen Namen, diese Arbeit zu machen.

Auf der anderen Seite, Sie bei Verwendung von nHibernate oder Castle Active statt entweder der oben in Ihrer eigenen Lösung zu replizieren.

Es kann einfacher sein, wenn Sie die User-Klasse in Ruhe lassen und damit umgehen die IDE es ist Schöpfung.

Oft ziehe ich eine eigene Klasse haben, um die Datenwieder behandeln. Angenommen, Sie nennen es das UserDataProvider und alle Anrufe schließlich eine User-Instanz durch diese Klasse gehen zu bekommen.

Der Konstruktor von UserDataProvider könnte eine globale Instanz des Datenkontextobjekt für die Wiederverwendung instanziiert. Es würde wie folgt aussehen (in C # und ungetesteten Code so mit mir tragen):

public class UserDataProvider 
{
    private UserDataContext _data = null;

    public UserDataProvider()
    {
        _data = new UserDataContext();
    }

    public User GetUser(int userID)
    {
        return _data.Users.FirstOrDefault(u => u.UserID == userID);
    }
}

Alternativ könnten setzen Sie Initialisierung in einer Eigenschaft und den Zugang, dass Eigentum für die Datenkontextverwendung.

public class UserDataProvider 
{
    private UserDataContext _dataContext;

    private UserDataContext DataContext 
    {
        get
        {
            if (_data == null)
                _data = new UserDataContext();

            return _data;
        }
    }

    public User GetUser(int userID)
    {
        return DataContext.Users.FirstOrDefault(u => u.UserID == userID);
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top