Festlegen von Fremdschlüsseln in Linq to SQL

8

Es ist bekannt, dass Sie Fremdschlüssel-IDs nicht direkt in Linq auf SQL setzen können, wenn die Entitäten bereits geladen wurden. Sie können jedoch die Entität anhand ihres Fremdschlüssels suchen und dann die Entität mithilfe der Entitätsbeziehung als fremde Entität festlegen. (Ich habe die enum hier herausgenommen und zur Vereinfachung ganzzahlige Werte verwendet). Wenn ich eine geladene Termin-Entität und eine zugeordnete AppoinmentStatus-Entität habe, kann ich dies nicht tun: -

%Vor%

Aber ich kann das tun: -

%Vor%

Ich habe so etwas mit meinem Code zu tun, und ich würde gerne umgestalten. Also ...

Ich könnte offensichtlich eine Hilfsmethode in einem Modul wie diesem verwenden: -

%Vor%

Ich könnte das sogar zu einer Erweiterungsmethode machen, so.

%Vor%

Ich könnte das auch in die Teilklasse Linq to SQL schreiben, so.

%Vor%

Außerdem könnte ich den Code in die partielle Klasse Linq to SQL Appointment Entity wie folgt einfügen: -

%Vor%

Was soll ich tun und warum, oder gibt es eine bessere Alternative?

    
Christopher Edwards 26.01.2009, 13:29
quelle

3 Antworten

3

Es gibt zwei Hauptschulen zu diesem Thema:

  1. Setze die Logik in die DataContext (partielle Klasse oder tatsächliche Klasse, wenn du deine DataContext von Hand codierst). Der Grund dafür ist, dass Ihr DataContext bereits über all Ihre verschiedenen Entitäten Bescheid weiß, sodass dies keine zusätzliche Kopplung erzeugt und nicht zu einem Klassenaufblähen führt.

    Der Nachteil ist natürlich, dass wenn Sie ein paar hundert dieser API-Methoden haben (und Sie werden wahrscheinlich, irgendwann) dann Ihre DataContext wird schnell zu einem Ball des Schlamms, mit jeder beliebigen Abfrage API gefüllt werden Jeder Programmierer entscheidet sich dafür einzuwerfen. Sie können versuchen, dies zu bereinigen, indem Sie verwandte Funktionen in verschiedene Instanzen derselben partiellen DataContext -Klasse trennen, aber das ist wirklich nur eine kosmetische Verbesserung.

  2. Setzen Sie die Logik in eine Repository-Klasse, d. h. eine AppointmentRepository . Zwei Vorteile dieses Ansatzes sind (a) die Möglichkeit, die Abhängigkeitsinjektion für das Repository und ein IoC-Framework zu nutzen, falls Sie sich dazu entschließen, Ihr Datenmodell zu ändern, und (b) die Tatsache, dass Sie bei Single Responsibility-Prinzip - es macht Sinn für die Methode, wo sie ist.

    Die Hauptnachteile, diese in Repositories zu setzen, sind: (a) Sie können sehr ähnliche Logik duplizieren, die sich bereits in Ihrem DataContext als Stored Procedures befindet; (b) sie haben eine Art von Kopfschmerzen, wenn es um Transaktionsmanagement geht (wenn Sie sie auch zum Speichern verwenden); und (c) Wenn Sie mit vielen benutzerdefinierten Abfragen beginnen, die speziell zugeschnittene DTOs für bestimmte Vorgänge oder Berichte zurückgeben, haben Sie zwei einfache Möglichkeiten, entweder ein Repository für jedes DTO zu erstellen oder einen Master zu erstellen "Dienstprogramm" -Repository für alle DTOs oder einige lose verwandte Gruppe von ihnen. Beide enden als ziemlich schlechtes Design.

Das sind die Kompromisse; nur Sie können entscheiden, welches für Ihre eigenen Zwecke besser ist.

Ich würde definitiv gegen den Ansatz der Erweiterungsmethode empfehlen, da Erweiterungsmethoden schwer zu finden sind (Sie können nicht einfach die Methode eingeben und sich von Intellisense holen lassen) relevante Referenz), und sie sind auch nicht notwendig, wenn Sie die ursprüngliche Klasse direkt ändern oder erweitern können.

Ich rate auch davon ab, die Appointment -Klasse zu erweitern; Einer der Gründe, warum wir Tools wie Linq To SQL verwenden, ist, dass wir mit POCO-Entitäten umgehen können, die nicht wissen müssen, woher sie kommen. Aus diesem Grund bin ich persönlich sehr gegen die Kopplung von Entitätsklassen an ihre DataContext - die Abhängigkeit sollte nur einseitig sein.

    
Aaronaught 31.01.2010, 02:27
quelle
1

Ich gebe diese Methoden in der Regel in die partielle Klasse für den DataContext ein, aufgrund der Theorie, dass diese Methoden gespeicherten Prozeduren in gewissem Sinne ähnlich sind, und gespeicherte Prozeduren als Methoden im DataContext manifestiert werden.

Unabhängig davon, wie Sie vorgehen, es lohnt sich auf jeden Fall zu refaktorieren, damit Sie diese Abfrage nur an einer Stelle haben und sich nicht wiederholen. Dies gibt Ihnen auch die Möglichkeit, die einfache Methode, die Sie beschrieben haben, durch eine ausgeklügeltere zu ersetzen, die eine kompilierte Version der Abfrage zwischenspeichert und wiederverwendet, ohne alle Aufrufer der Methode zu aktualisieren.

    
Bryn Keller 31.01.2010 01:55
quelle
0

Normalerweise sieht der Setter von AppointmentStatusId folgendermaßen aus: (Code in C #, aber es sollte leicht zu bekommen sein)

%Vor%

Also, wenn ich Sie wäre, würde ich eine Methode SetAppointmentStatusId (int statusId) zu der partiellen Datei hinzufügen, die mit dem vom Designer erstellten Teil kommt, und weitere hinzufügen, wenn sie für andere Eigenschaften benötigt werden. Sie können sogar festlegen, dass der Setter der Eigenschaft privat sein soll (wählen Sie vom Designer aus die Eigenschaft aus, und drücken Sie F4, um für das VS-Eigenschaftenfenster die Zugriffsmöglichkeit zu ändern.) In dieser Methode würde ich Code schreiben, der mit dem Setter identisch ist, außer dass er diesen Teil NICHT enthält:

%Vor%     
Meligy 10.01.2010 08:39
quelle

Tags und Links