2016-05-27 7 views
4

Leider Entity Framework Core 1.0 (früher Entity Framework 7) unterstützt noch nicht Ansichten, und ich versuche, es "vorzutäuschen" mit einer Tabelle.Wie kann ich Datenbankansichten in einem gerüsteten DbContext mit Entity Framework Core 1.0 (EF7) verwenden

Allerdings das Gerüst dotnet dbcontext ef scaffold Befehl erkennt derzeit nicht oder generieren Ansichten, und ich möchte einen einzelnen DbContext, der Abfragen einer Ansicht und Aktualisierung von Tabellen ermöglicht. Gibt es eine Möglichkeit, dies zu tun?

Dies ist der Befehl, den ich die DbContext Gerüst verwenden:

dotnet ef dbcontext scaffold -c MyStoreContext -o Model "Data Source=(local);Initial Catalog=DBNAME;Integrated Security=True" Microsoft.EntityFrameworkCore.SqlServer --force 

(Das alles Klasse meines Modells bringt ein Model Verzeichnis und zwingt sie überschrieben werden.)

Hinweis: Der Grund, ich möchte wirklich eine Ansicht zu verwenden ist für GROUP BY-Logik, die nicht unterstützt wird entweder in EF-Core 1.0

Antwort

1

Hier ist, was ich kam mit:

Ich erstelle eine partielle Klasse, die erbt von DbContext und fügen Sie dann jede neue Logik hinzu, indem Sie die OnModelCreating Methode überschreiben.

Schließlich sollte der EF-Gerüstbauer (ich hoffe) in der Lage sein, Ansichten für mich zu erstellen, also rufe ich in der Zwischenzeit die Klasse MyStoreContext_WithViews an, damit ich eine Suche durchführen und irgendwann ersetzen kann, um sie zu aktualisieren.

Die Datenbankansicht in diesem Beispiel heißt RepeatOrderSummaryView.

Ich musste hier alle Spalten manuell zu meiner Ansichtsklasse hinzufügen (da der Gerüstbauer dies nicht unterstützt). Das ist im Moment in Ordnung.

Es gibt keinen Schlüssel in der Ansicht, aber EF benötigt einen Schlüssel, also erstelle ich nur einen falschen mit einer der Spalten.

namespace MyStore.EF.Model 
{ 
    public partial class MyStoreContext_WithViews : MyStoreContext 
    {  
     protected override void OnModelCreating(ModelBuilder modelBuilder) 
     { 
      base.OnModelCreating(modelBuilder); 

      modelBuilder.Entity<RepeatOrderSummaryView>(entity => 
      { 
       entity.HasKey(e => new { e.FirstOrder_Date }) 
        .HasName("PK_FAKEKEY"); 
      }); 
     } 

     public virtual DbSet<RepeatOrderSummaryView> RepeatOrderSummaryView { get; set; }  
    } 

    [Table("RepeatOrderSummaryView")] 
    public partial class RepeatOrderSummaryView 
    { 
     public DateTime OrderDate { get; set; } 
     public bool HasShipped { get; set; } 
    } 
} 

war ich dann in der Lage, diese Abfrage gegen die Ansicht erfolgreich auszuführen:

RRStoreContext_WithViews ctx = new RRStoreContext_WithViews(); 
var data = ctx.RepeatOrderSummaryView.Where(x => x.HasShipped == true); 

Da diese Klasse von meinem generierten DbContext nur erbt (MyStoreContext) ich natürlich den ganzen Rest der Tabellen verwenden können das waren gerüstet.

Nicht auf aktualisierbare Ansichten getestet - natürlich, wenn Sie dies versuchen, müssen Sie eine echte PK definiert.


Weil Sie nicht ‚echte‘ Einheiten oder notwendigerweise Elemente mit einem echten Schlüssel definiert Rückkehr sollten Sie .AsNoTracking() verwenden. Ich habe weniger Ergebnisse in meiner Ergebnismenge gefunden, als ich erwartet hatte, und es war, weil es eine Schlüsselübereinstimmung machte und dachte, dass es das Objekt bereits im Speicher hatte.

Achten Sie darauf, sorgfältig zu testen, um sicherzustellen, dass die Anzahl der Ergebnisse wie erwartet ist - oder Sie werden große Probleme haben.

What difference does .AsNoTracking() make?

5

Für mich war meiner Meinung nach in einem anderen Schema, also musste ich ein Attribut auf der Modellklasse ändern:

using System.ComponentModel.DataAnnotations.Schema; 

namespace API.DataAccess 
{ 
    [Table("MyViewName", Schema = "SomeSchema")] 
    public class MyViewName 
    { 
     //props 
    } 
} 

Zur Vollständigkeit der Einheit Code:

protected override void OnModelCreating(ModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<MyViewName>(entity => 
    { 
     entity.HasKey(e => new { e.SomeColumn }).HasName("PK_FAKEKEY"); 
      entity.Property(e => e.SomeColumn).IsRequired(); 
      entity.Property(e => e.SomeColumn2); 
      entity.Property(e => e.SomeColumn3); 
    }); 
} 
Verwandte Themen