2011-09-18 13 views
64

Come posso utilizzare la vista del database in entità codice del framework prima,come utilizzare viste in codice di primo quadro entità

+0

Nessuna delle risposte di seguito spiegano come creare una vista utilizzando migrazioni EF. Vedi [questa risposta] (https://stackoverflow.com/a/18707413/1185136) per una domanda simile. –

risposta

68

Se, come me, si è interessati solo a entità mappatura proveniente da un altro database (un ERP in il mio caso) per metterli in relazione con entità specifiche della vostra applicazione, quindi potete usare le viste mentre utilizzate una tabella (mappate la vista allo stesso modo!). Ovviamente, se si tenta di aggiornare tali entità, si otterrà un'eccezione se la vista non è aggiornabile. La procedura è la stessa come nel caso di soggetti normali (sulla base di una tabella):

  1. creare una classe POCO per la vista; per esempio FooView
  2. Aggiungere la proprietà DbSet nella classe DbContext
  3. Utilizzare un file FooViewConfiguration per impostare un nome diverso per la vista (utilizzando ToTable ("Pippo"); nel costruttore) o per impostare particolari proprietà

    public class FooViewConfiguration : EntityTypeConfiguration<FooView>  
    { 
        public FooViewConfiguration() 
        { 
         this.HasKey(t => t.Id); 
         this.ToTable("myView"); 
        } 
    } 
    
  4. aggiungere il file FooViewConfiguration al ModelBuilder, ad esempio il metodo ovveriding OnModelCreating del Contesto:

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

+1 per non presupporre che "Code First" == generazione automatica del database – onetwopunch

+1

Anche se è auto-gen, è possibile creare script delle viste in IDatabaseInitializer e fintanto che si utilizza una "classe ViewName: Entity" che corrisponde a questo come la risposta sta suggerendo, starai bene. –

+3

@DaveJellison ti piacerebbe elaborare, o fornire un collegamento sull'aggiunta di una vista come parte di un IDatabaseInitializer –

8

Se tutto ciò che si desidera è un gruppo di oggetti de-normalizzati, è possibile che sia stata creata una proprietà pubblica di tipo get-only IQueryable<TDenormolized> nella classe DbContext.

Nel get si restituisce un risultato Linq per proiettare i valori de-normoalizzati negli oggetti de-normalizzati. Ciò potrebbe essere migliore della scrittura di una vista DB perché si sta programmando, non si è limitati utilizzando solo le istruzioni select. Inoltre è sicuro in termini di tempo di compilazione.

Basta fare attenzione a non attivare le enumerazioni come le chiamate ToList(), che interromperanno la query posticipata e si potrebbe finire con ottenere un milione di record dal database e filtrarli sul server delle applicazioni.

Non so se questo è il modo giusto, ma ho provato e funziona per me.

+4

Uno dei motivi per cui vorrei utilizzare le viste è che l'SQL generato da EF non è sempre "bello" - abbiamo alcune gerarchie di ereditarietà nel nostro modello (trovato fuori circa le insidie ​​troppo tardi ...) e l'utilizzo di viste ci consente di creare manualmente l'SQL. Solo un contrappunto sul motivo per cui sarebbe preferibile una visualizzazione – Carl

+1

Un altro motivo per non farlo potrebbe essere l'utilizzo di espressioni di tabella comuni ricorsive, che non sono disponibili in LINQ. Ma per il resto questo è un buon consiglio per scenari più semplici. –

+0

L'utilizzo di una proprietà anziché di una vista non è un'opzione se si desidera utilizzare i vantaggi di una vista * indicizzata *. –

2

Questo può essere un aggiornamento, ma per utilizzare prima le viste con il codice EF è sufficiente aggiungere [Table ("NameOfView")] all'inizio della classe e tutto dovrebbe funzionare correttamente senza dover passare attraverso tutti i cerchi che tutti gli altri stanno andando attraverso. Inoltre dovrai segnalare una delle colonne come una colonna [chiave]. Ecco il mio codice di esempio qui sotto per implementarlo.

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; } 
    } 
} 

E qui è ciò che il contesto appare come

using System.Data.Entity; 

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

Questa è la stessa della risposta accettata, tranne per il fatto che utilizza DataAnnotations mentre la risposta accettata utilizza l'API Fluid EF. –

Problemi correlati