come utilizzare le viste in code first entity framework [chiuso]


87

Come posso utilizzare prima la visualizzazione del database nel codice del framework di entità,


2
Nessuna delle risposte seguenti spiega come creare una vista usando le migrazioni EF. Vedi questa risposta per una domanda simile.
Rudey

Ecco un thread con esattamente la stessa domanda. - stackoverflow.com/questions/13593845/…
Div Tiwari

Prova la mia soluzione . Impedisce la generazione della migrazione per le tabelle contrassegnate come viste
kogoia

Risposte:


95

Se, come me, sei interessato solo a mappare entità provenienti da un altro database (un erp nel mio caso) per metterle in relazione con entità specifiche della tua applicazione, allora puoi usare le viste come usi una tabella (mappare la vista in allo stesso modo!). Ovviamente, se provi ad aggiornare quelle entità, otterrai un'eccezione se la vista non è aggiornabile. La procedura è la stessa del caso delle entità normali (basate su una tabella):

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

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

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

64
+1 per non presumere che "Code First" == generazione automatica del database
onetwopunch il

3
@DaveJellison vorresti elaborare o fornire un collegamento sull'aggiunta di una vista come parte di un IDatabaseInitializer
Ralph Shillington,

18
Sono solo io o tutti stanno ottenendo una tabella vuota creata dalla migrazione? C'è un modo per evitarlo?
Kremena Lalova

4
Solo assicurandoci qui, questa soluzione ci ha richiesto di creare la vista sul database SQL in anticipo esternamente? È possibile definire la visualizzazione nel codice e inserirla nel database tramite il comando Add-Migration / Update-Database?
frostshoxx

6
Poche cose. 1. Questa risposta non menziona che devi creare la vista manualmente usando SQL, questo può essere fatto usando una migrazione. 2. Non è necessario configurare il nome della vista se il nome della classe corrisponde al nome della vista. 3. Puoi usare DataAnnotations in questo modo:, [Table("myView")]questo è probabilmente più semplice rispetto all'utilizzo della creazione di un file EntityTypeConfiguration.
Rudey

23

Questo potrebbe essere un aggiornamento, ma per usare le viste con il codice EF prima aggiungi semplicemente [Table ("NameOfView")] all'inizio della classe e tutto dovrebbe funzionare correttamente senza dover passare attraverso tutti i cerchi che tutti gli altri stanno attraversando. Inoltre dovrai segnalare una delle colonne come una colonna [chiave]. Ecco il mio codice di esempio di seguito 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; }
    }
}

Ed ecco come appare il contesto

using System.Data.Entity;

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

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

4
In realtà no, non lo è. Ho provato, senza successo, sulla risposta accettata e non ha funzionato bene per me. Ma poi sto usando le migrazioni, quindi questo potrebbe avere avuto un impatto sulle cose. Ho scoperto che dovevo prima fare le mie migrazioni POI aggiungere la mia classe di visualizzazione poiché esisteva già nel database. Lo gestiremmo esattamente allo stesso modo se avessimo già tabelle esistenti nel database. Poiché una vista è una "tabella virtuale", la sintassi della tabella in Entity Framework funziona ancora.
Charles Owen

11

Se tutto ciò che desideri è un mucchio di oggetti denormalizzati, potresti semplicemente creare una IQueryable<TDenormolized>proprietà di sola ricezione pubblica nella tua DbContextclasse.

In getrestituisci un risultato Linq per proiettare i valori de-normoalizzati nei tuoi oggetti de-normalizzati. Questo potrebbe essere meglio che scrivere una vista DB perché stai programmando, non sei limitato usando solo le selectistruzioni. Inoltre è sicuro per il tipo in fase di compilazione.

Fai solo attenzione a non attivare enumerazioni come le ToList()chiamate, che interromperanno la query differita e potresti finire con il recuperare un milione di record dal database e filtrarli sul tuo server delle applicazioni.

Non so se sia la strada giusta, ma ci ho provato e per me funziona.


6
Uno dei motivi per cui mi piacerebbe usare le viste è che l'SQL generato da EF non è sempre 'carino': abbiamo alcune gerarchie di ereditarietà nel nostro modello (abbiamo scoperto le insidie ​​troppo tardi ...) e l'uso delle viste ci consente per creare manualmente l'SQL. Solo un contrappunto sul motivo per cui sarebbe preferibile una visione
Carl

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

1
L'utilizzo di una proprietà invece di una vista non è un'opzione se si desidera sfruttare i vantaggi di una vista indicizzata .
Rudey

"non sei limitato utilizzando solo istruzioni select". Cosa intendi con questo? Tutto ciò che puoi fare con LINQ può essere fatto usando le istruzioni SELECT, lo stesso non si può dire per il contrario.
Rudey

3

So che questa è una vecchia domanda e ci sono molte risposte qui, ma ho costretto a un problema quando uso questa risposta e si è verificato un errore quando utilizzo il comando update-database nella console di Gestione pacchetti:

Esiste già un oggetto denominato "..." nel database.

e utilizzo questi passaggi per risolvere questo problema:

  1. esegui questo comando nella console di Gestione pacchetti: Add-migration intial
  2. Nella cartella Migrations, puoi trovare il file ..._ intial.cs, aprirlo e commentare o eliminare qualsiasi comando relativo alla tua classe che desideri mappare
  3. ora puoi normalmente utilizzare il comando update-database per qualsiasi altra modifica ai tuoi modelli

spero che sia d'aiuto.


1
Grazie! Questo ha davvero aiutato! Come extra, invece di rimuovere semplicemente il codice generato con EF Migrations, puoi invece aggiungerlo lì migrationBuilder.Sql("CREATE OR REPLACE VIEW ...); In modo che i colleghi possano utilizzarlo anche per aggiornare il proprio database.
Rich_Rich
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.