In keiner der folgenden Antworten wird erläutert, wie Sie mithilfe von EF-Migrationen eine Ansicht erstellen. Siehe diese Antwort für eine ähnliche Frage.
Probieren Sie meine Lösung aus . Es verhindert die Generierung von Migrationen für Tabellen, die als Ansichten markiert sind
kogoia
Antworten:
95
Wenn Sie wie ich nur daran interessiert sind, Entitäten aus einer anderen Datenbank (in meinem Fall ein ERP) zuzuordnen, um sie mit Entitäten zu verknüpfen, die für Ihre Anwendung spezifisch sind, können Sie die Ansichten verwenden, während Sie eine Tabelle verwenden (ordnen Sie die Ansicht in zu in der gleichen Weise!). Wenn Sie versuchen, diese Entitäten zu aktualisieren, erhalten Sie natürlich eine Ausnahme, wenn die Ansicht nicht aktualisierbar ist. Die Vorgehensweise ist dieselbe wie bei normalen (auf einer Tabelle basierenden) Entitäten:
Erstellen Sie eine POCO-Klasse für die Ansicht. Zum Beispiel FooView
Fügen Sie die DbSet-Eigenschaft in die DbContext-Klasse ein
Verwenden Sie eine FooViewConfiguration-Datei, um einen anderen Namen für die Ansicht festzulegen (mithilfe von ToTable ("Foo"); im Konstruktor) oder um bestimmte Eigenschaften festzulegen
+1 für die Annahme, dass "Code First" == automatische Datenbankgenerierung
onetwopunch
3
@ DaveJellison möchten Sie näher erläutern oder einen Link zum Hinzufügen einer Ansicht als Teil eines IDatabaseInitializer
Ralph Shillington
18
Ist es nur ich oder bekommt jeder eine leere Tabelle, die durch die Migration erstellt wurde? Gibt es eine Möglichkeit, dies zu vermeiden?
Kremena Lalova
4
Um sicherzustellen, dass diese Lösung erforderlich ist, müssen wir diese Ansicht zuvor extern in der SQL-Datenbank erstellen. Ist es möglich, die Ansicht im Code zu definieren und sie mit dem Befehl Add-Migration / Update-Database in die Datenbank einfügen zu lassen?
Frostshoxx
6
Ein paar Dinge. 1. In dieser Antwort wird nicht erwähnt, dass Sie die Ansicht manuell mit SQL erstellen müssen. Dies kann mithilfe einer Migration erfolgen. 2. Sie müssen den Ansichtsnamen nicht konfigurieren, wenn der Klassenname mit dem Ansichtsnamen übereinstimmt. 3. Sie können DataAnnotations wie folgt verwenden: [Table("myView")]Dies ist wohl einfacher als das Erstellen von a EntityTypeConfiguration.
Rudey
22
Dies kann ein Update sein, aber um Ansichten mit EF-Code zu verwenden, fügen Sie einfach zuerst [Tabelle ("NameOfView")] an die Spitze der Klasse hinzu, und alles sollte einwandfrei funktionieren, ohne alle Rahmen durchlaufen zu müssen, die alle anderen durchlaufen. Außerdem müssen Sie eine der Spalten als [Schlüssel] -Spalte melden. Hier ist mein Beispielcode unten, um ihn zu implementieren.
Dies entspricht der akzeptierten Antwort, außer dass DataAnnotations verwendet wird, während die akzeptierte Antwort die EF Fluid-API verwendet.
Rudey
4
Nein, ist es eigentlich nicht. Ich habe erfolglos versucht, die akzeptierte Antwort zu finden, und es hat bei mir nicht gut funktioniert. Aber dann verwende ich Migrationen, sodass sich dies möglicherweise auf die Dinge ausgewirkt hat. Ich stellte fest, dass ich zuerst meine Migrationen durchführen musste, DANN meine Ansichtsklasse hinzufügen, da sie bereits in der Datenbank vorhanden war. Wir würden genauso vorgehen, wenn wir bereits vorhandene Tabellen in der Datenbank hätten. Da eine Ansicht eine "virtuelle Tabelle" ist, funktioniert die Tabellensyntax im Entity Framework weiterhin.
Charles Owen
11
Wenn Sie nur eine Reihe von nicht normalisierten Objekten benötigen, haben Sie möglicherweise nur eine öffentliche Nur-Get- IQueryable<TDenormolized>Eigenschaft in Ihrer DbContextKlasse erstellt.
In geben getSie ein Linq-Ergebnis zurück, um die de-normoalisierten Werte in Ihre de-normalisierten Objekte zu projizieren. Dies ist möglicherweise besser als das Schreiben einer DB-Ansicht, da Sie beim Programmieren nicht nur selectAnweisungen verwenden. Außerdem ist die Kompilierungszeit sicher.
Achten Sie nur darauf ToList(), dass Sie keine Aufzählungen wie Aufrufe auslösen , da dies die verzögerte Abfrage unterbricht. Möglicherweise erhalten Sie eine Million Datensätze aus der Datenbank zurück und filtern sie auf Ihrem Anwendungsserver.
Ich weiß nicht, ob dies der richtige Weg ist, aber ich habe es versucht und es funktioniert für mich.
Einer der Gründe, warum ich Ansichten verwenden möchte, ist, dass das von EF generierte SQL nicht immer "nett" ist - wir haben einige Vererbungshierarchien in unserem Modell (zu spät über die Fallstricke herausgefunden ...) und die Verwendung von Ansichten ermöglicht es uns um das SQL manuell zu erstellen. Nur ein Kontrapunkt, warum eine Ansicht vorzuziehen wäre
Carl
2
Ein weiterer Grund, dies nicht zu tun, könnte die Verwendung rekursiver allgemeiner Tabellenausdrücke sein, die in LINQ nicht verfügbar sind. Ansonsten ist dies ein guter Rat für einfachere Szenarien.
Tom Pažourek
1
Die Verwendung einer Eigenschaft anstelle einer Ansicht ist keine Option, wenn Sie die Vorteile einer indizierten Ansicht nutzen möchten .
Rudey
"Sie sind nicht darauf beschränkt, nur select-Anweisungen zu verwenden". Was meinst du damit? Alles, was Sie mit LINQ tun können, kann mit SELECT-Anweisungen erfolgen, das Gleiche gilt nicht umgekehrt.
Rudey
3
Ich weiß, dass dies eine alte Frage ist und es hier viele Antworten gibt, aber ich habe ein Problem erzwungen, als ich diese Antwort verwendet habe, und ein Fehler ist aufgetreten, als ich den Befehl update-database in der Package Manager-Konsole verwendet habe:
In der Datenbank befindet sich bereits ein Objekt mit dem Namen '...'.
und ich benutze diese Schritte, um dieses Problem zu lösen:
Führen Sie diesen Befehl in Package Manager Console: Add-Migration Intial aus
Im Ordner "Migrationen" finden Sie die Datei ..._ intial.cs, öffnen sie und kommentieren oder löschen alle Befehle, die sich auf Ihre Klasse beziehen, die Sie zuordnen möchten
Jetzt können Sie normalerweise den Befehl update-database für jede andere Änderung an Ihren Modellen verwenden
Vielen Dank! Das hat wirklich geholfen! Anstatt nur den mit EF Migrations generierten Code zu entfernen, können Sie ihn stattdessen hinzufügen migrationBuilder.Sql("CREATE OR REPLACE VIEW .... Damit Kollegen damit auch ihre Datenbank aktualisieren können.
Antworten:
Wenn Sie wie ich nur daran interessiert sind, Entitäten aus einer anderen Datenbank (in meinem Fall ein ERP) zuzuordnen, um sie mit Entitäten zu verknüpfen, die für Ihre Anwendung spezifisch sind, können Sie die Ansichten verwenden, während Sie eine Tabelle verwenden (ordnen Sie die Ansicht in zu in der gleichen Weise!). Wenn Sie versuchen, diese Entitäten zu aktualisieren, erhalten Sie natürlich eine Ausnahme, wenn die Ansicht nicht aktualisierbar ist. Die Vorgehensweise ist dieselbe wie bei normalen (auf einer Tabelle basierenden) Entitäten:
Verwenden Sie eine FooViewConfiguration-Datei, um einen anderen Namen für die Ansicht festzulegen (mithilfe von ToTable ("Foo"); im Konstruktor) oder um bestimmte Eigenschaften festzulegen
Fügen Sie die FooViewConfiguration-Datei zum modelBuilder hinzu, z. B. über die OnModelCreating-Methode des Kontexts:
quelle
[Table("myView")]
Dies ist wohl einfacher als das Erstellen von aEntityTypeConfiguration
.Dies kann ein Update sein, aber um Ansichten mit EF-Code zu verwenden, fügen Sie einfach zuerst [Tabelle ("NameOfView")] an die Spitze der Klasse hinzu, und alles sollte einwandfrei funktionieren, ohne alle Rahmen durchlaufen zu müssen, die alle anderen durchlaufen. Außerdem müssen Sie eine der Spalten als [Schlüssel] -Spalte melden. Hier ist mein Beispielcode unten, um ihn zu implementieren.
Und so sieht der Kontext aus
quelle
Wenn Sie nur eine Reihe von nicht normalisierten Objekten benötigen, haben Sie möglicherweise nur eine öffentliche Nur-Get-
IQueryable<TDenormolized>
Eigenschaft in IhrerDbContext
Klasse erstellt.In geben
get
Sie ein Linq-Ergebnis zurück, um die de-normoalisierten Werte in Ihre de-normalisierten Objekte zu projizieren. Dies ist möglicherweise besser als das Schreiben einer DB-Ansicht, da Sie beim Programmieren nicht nurselect
Anweisungen verwenden. Außerdem ist die Kompilierungszeit sicher.Achten Sie nur darauf
ToList()
, dass Sie keine Aufzählungen wie Aufrufe auslösen , da dies die verzögerte Abfrage unterbricht. Möglicherweise erhalten Sie eine Million Datensätze aus der Datenbank zurück und filtern sie auf Ihrem Anwendungsserver.Ich weiß nicht, ob dies der richtige Weg ist, aber ich habe es versucht und es funktioniert für mich.
quelle
Ich weiß, dass dies eine alte Frage ist und es hier viele Antworten gibt, aber ich habe ein Problem erzwungen, als ich diese Antwort verwendet habe, und ein Fehler ist aufgetreten, als ich den Befehl update-database in der Package Manager-Konsole verwendet habe:
und ich benutze diese Schritte, um dieses Problem zu lösen:
ich hoffe es hilft.
quelle
migrationBuilder.Sql("CREATE OR REPLACE VIEW ...
. Damit Kollegen damit auch ihre Datenbank aktualisieren können.