Verwendung von Ansichten im Code First Entity Framework [geschlossen]


87

Wie kann ich die Datenbankansicht zuerst im Entity Framework-Code verwenden?


2
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.
Rudey

Hier ist ein Thread mit genau der gleichen Frage. - stackoverflow.com/questions/13593845/…
Div Tiwari

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:

  1. Erstellen Sie eine POCO-Klasse für die Ansicht. Zum Beispiel FooView
  2. Fügen Sie die DbSet-Eigenschaft in die DbContext-Klasse ein
  3. 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

    public class FooViewConfiguration : EntityTypeConfiguration<FooView>      
    {
        public FooViewConfiguration()
        {
            this.HasKey(t => t.Id);
            this.ToTable("myView");
        }
    }
    
  4. Fügen Sie die FooViewConfiguration-Datei zum modelBuilder hinzu, z. B. über die OnModelCreating-Methode des Kontexts:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new FooViewConfiguration ());
    }
    

64
+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.

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace SomeProject.Data
{
    [Table("SomeView")]
    public class SomeView
    {
        [Key]
        public int NameID { get; set; }
        public string Name { get; set; }
    }
}

Und so sieht der Kontext aus

using System.Data.Entity;

namespace SomeProject.Data
{
    public class DatabaseContext : DbContext
    {
        public DbSet<SomeView> SomeViews { get; set; }
    }
}

1
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.


6
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:

  1. Führen Sie diesen Befehl in Package Manager Console: Add-Migration Intial aus
  2. 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
  3. Jetzt können Sie normalerweise den Befehl update-database für jede andere Änderung an Ihren Modellen verwenden

ich hoffe es hilft.


1
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.
Rich_Rich
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.