C # abstrakte Basisklasse für allgemeine Spalten in LINQ

8

Das ist was ich bisher habe

%Vor%

Mein Problem ist, dass das Mapping nicht funktioniert:

  

Datenelement 'System.Guid [oder System.Int32] ID' des Typs   'X'   ist nicht Teil des Mappings für den Typ   'X'. Ist das Mitglied oben?   die Wurzel einer Vererbungshierarchie?

Bevor ich versuche, die Attribute zu mappen, habe ich das stattdessen:

  

Schlüssel-ID des Schlüssels konnte nicht gefunden werden   'Id' am Typ 'X'. Der Schlüssel könnte falsch sein   oder das Feld oder die Eigenschaft auf 'X' hat   änderte Namen.

Ich habe versucht, K zu Guid zu ändern, und es funktioniert, aber warum? Ich sehe nicht, wie generische Typisierung hier ein Problem ist

Ich bin mir nicht ganz sicher, ob ich die Schnittstelle auch wirklich brauchte, ich kann mich nicht wirklich erinnern, warum ich sie hinzugefügt habe.

Die Frage wäre also: Wie kann ich einen solchen Kurs funktionieren lassen? Ich möchte es, damit ich auf eine allgemein benannte PK (Id) zugreifen kann, die immer den Typ K [welche Guid oder Int32] ist, und grundlegende Funktionen wie select und delete by Id

umgestalten

Danke!

BEARBEITEN:

das funktioniert

%Vor%

Was ich will, wäre im Prinzip das Gleiche, Guid durch K ersetzen und die Klasse BaseEntity machen (damit ich die gleiche Klasse für Int32 und Guid PKs verwenden kann)     

bevacqua 07.10.2010, 00:22
quelle

1 Antwort

8

Was Sie tun möchten, funktioniert nicht mit LINQ to SQL. Um die Vererbung mit LINQ to SQL zu verwenden, müssen Sie das Attribut [InheritanceMapping] für Ihre Basisklasse verwenden. Nehmen wir an, Sie haben eine Basisklasse namens Fahrzeug und eine Unterklasse namens Motorrad:

%Vor%

Damit diese Vererbung in LINQ to SQL funktioniert, müssen Sie die [VererbungMapping] auf die Basisklasse anwenden und Sie müssen auch eine Diskriminatorspalte (zB VehicleType in der obigen) haben Beispiel). Beachten Sie, dass der Code in der Vererbungszuordnung "1" ist. Das heißt, wenn der VehicleType aus der Datenbank "1" ist, wird die Motorrad-Unterklasse erstellt. Sie wenden ein [InheritanceMapping] -Attribut auf die Basisklasse für jede -Subklasse an, die Sie unterstützen.

Aus puristischer Sicht ist dies eine Verletzung von OO, weil die Basisklasse über ihre Unterklassen weiß. Dieses bisschen Seltsames bringt die Leute in der Regel dazu, wie LINQ to SQL die Vererbung implementiert. Aber da hast du es.

Aktualisieren Das funktioniert:

%Vor%

Beachten Sie, dass das Attribut [Spalte] für die Id-Eigenschaft nicht vorhanden ist. Beachten Sie auch, dass ich es abstrakt gemacht habe. Die implementierende Klasse sieht so aus:

%Vor%

Beachten Sie, dass die Id-Eigenschaft in dieser Klasse ein [Column] -Attribut besitzt und ich die abstrakte Eigenschaft überschreibe. Also habe ich überprüft, dass das funktioniert.

Nachdem ich das gesagt habe, gibt es eine Reihe von Gründen, warum ich Ihr aktuelles Design in Frage stelle. Zuerst haben Sie Ihre Datenzugriffsmethoden als Teil Ihrer Entität und viele Leute (einschließlich mir selbst) betrachten dies als eine Verletzung der Trennung von Bedenken. Sie könnten hier das Repository-Muster einführen und ein Repository für jede Entität haben - dieses Repository basierend auf dem Typ und Schlüssel generisch machen. Die andere Sache, die an dem obigen Ansatz seltsam ist, ist, dass die BaseEntity eine Id-Eigenschaft hat und die Unterklasse (in meinem Beispiel die Contact-Klasse) auch eine Eigenschaft von Id hat (um Linq To Sql glücklich zu machen). Musste die Id-Eigenschaft in der Basisklasse abstrahieren und dann im Implementierer überschreiben. Dies verstößt gegen DRY, weil ich dies für jede Entität tun muss. Aber das ist eine andere Sache, die das Ergebnis von Ringen ist, die Sie durchlaufen müssen, um LINQ zu SQL glücklich zu machen. Aber es wird funktionieren! :)

    
Steve Michelotti 07.10.2010, 01:25
quelle