comment utiliser les vues dans la première structure d'entité de code [fermé]


87

Comment puis-je utiliser d'abord la vue de la base de données dans le code du cadre d'entité,


2
Aucune des réponses ci-dessous n'explique comment créer une vue à l'aide de migrations EF. Voir cette réponse pour une question similaire.
Rudey

Voici un fil avec exactement la même question. - stackoverflow.com/questions/13593845/…
Div Tiwari

Essayez ma solution . Il empêche la génération de migration pour les tables marquées comme vues
kogoia

Réponses:


95

Si, comme moi, vous êtes uniquement intéressé par la cartographie d'entité provenant d'une autre base de données (un erp dans mon cas) pour les relier à des entités spécifiques de votre application, alors vous pouvez utiliser les vues comme vous utilisez une table (mapper la vue dans de la même façon!). Évidemment, si vous essayez de mettre à jour ces entités, vous obtiendrez une exception si la vue ne peut pas être mise à jour. La procédure est la même que dans le cas des entités normales (basées sur une table):

  1. Créez une classe POCO pour la vue; par exemple FooView
  2. Ajouter la propriété DbSet dans la classe DbContext
  3. Utilisez un fichier FooViewConfiguration pour définir un nom différent pour la vue (en utilisant ToTable ("Foo"); dans le constructeur) ou pour définir des propriétés particulières

    public class FooViewConfiguration : EntityTypeConfiguration<FooView>      
    {
        public FooViewConfiguration()
        {
            this.HasKey(t => t.Id);
            this.ToTable("myView");
        }
    }
    
  4. Ajoutez le fichier FooViewConfiguration au modelBuilder, par exemple en survolant la méthode OnModelCreating du Context:

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

64
+1 pour ne pas avoir supposé que "Code First" == génération automatique de la base de données
onetwopunch

3
@DaveJellison voudriez-vous élaborer, ou fournir un lien sur l'ajout d'une vue dans le cadre d'un IDatabaseInitializer
Ralph Shillington

18
Est-ce juste moi, ou tout le monde obtient une table vide créée par la migration? Y a-t-il un moyen d'éviter cela?
Kremena Lalova

4
Assurez-vous simplement ici que cette solution nous oblige à créer au préalable View sur la base de données SQL en externe? Est-il possible de définir la vue dans le code et de la remplir dans la base de données via la commande Add-Migration / Update-Database?
frostshoxx

6
Quelques choses. 1. Cette réponse ne mentionne pas que vous devez créer la vue manuellement à l'aide de SQL, cela peut être fait à l'aide d'une migration. 2. Vous n'avez pas à configurer le nom de la vue si le nom de la classe correspond au nom de la vue. 3. Vous pouvez utiliser DataAnnotations comme ceci:, [Table("myView")]c'est sans doute plus simple que d'utiliser la création d'un fichier EntityTypeConfiguration.
Rudey

23

Cela peut être une mise à jour, mais pour utiliser les vues avec EF Code, ajoutez d'abord simplement [Table ("NameOfView")] en haut de la classe et tout devrait fonctionner correctement sans avoir à passer par tous les obstacles que tout le monde traverse. Vous devrez également signaler l'une des colonnes en tant que colonne [clé]. Voici mon exemple de code ci-dessous pour l'implémenter.

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

Et voici à quoi ressemble le contexte

using System.Data.Entity;

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

2
Ceci est identique à la réponse acceptée, sauf que cela utilise DataAnnotations tandis que la réponse acceptée utilise l'API EF Fluid.
Rudey

4
En fait non, ce n'est pas le cas. J'ai essayé, sans succès, la réponse acceptée et cela n'a pas bien fonctionné pour moi. Mais ensuite, j'utilise Migrations, donc cela peut avoir un impact sur les choses. J'ai trouvé que je devais d'abord faire mes migrations PUIS ajouter ma classe de vue car elle existait déjà dans la base de données. Nous le traiterions exactement de la même manière si nous avions déjà des tables existantes dans la base de données. Puisqu'une vue est une «table virtuelle», la syntaxe de la table dans Entity Framework fonctionne toujours.
Charles Owen

11

Si tout ce que vous voulez est un groupe d'objets dé-normalisés, vous pouvez simplement créer une IQueryable<TDenormolized>propriété publique en lecture seule dans votre DbContextclasse.

Dans le, getvous renvoyez un résultat Linq pour projeter les valeurs dé-normoalisées dans vos objets dé-normalisés. Cela peut être mieux que d'écrire une vue DB car vous programmez, vous n'êtes pas limité par l'utilisation d' selectinstructions uniquement . Il est également sûr de type de compilation.

Faites juste attention à ne pas déclencher d'énumérations comme des ToList()appels, qui briseraient la requête différée et vous pourriez finir par récupérer un million d'enregistrements de la base de données et les filtrer sur votre serveur d'applications.

Je ne sais pas si c'est la bonne façon, mais j'ai essayé et ça marche pour moi.


6
L'une des raisons pour lesquelles j'aimerais utiliser des vues est que le SQL généré par EF n'est pas toujours `` sympa '' - nous avons des hiérarchies d'héritage dans notre modèle (nous avons découvert les pièges trop tard ...) et l'utilisation des vues nous permet pour créer manuellement le SQL. Juste un contrepoint sur les raisons pour lesquelles une vue serait préférable
Carl

2
Une autre raison de ne pas le faire peut être l'utilisation d'expressions de table communes récursives, qui ne sont pas disponibles dans LINQ. Mais sinon, c'est un bon conseil pour des scénarios plus simples.
Tom Pažourek

1
L'utilisation d'une propriété au lieu d'une vue n'est pas une option si vous souhaitez profiter des avantages d'une vue indexée .
Rudey

"vous n'êtes pas limité en utilisant uniquement des instructions select". Que veux-tu dire par là? Tout ce que vous pouvez faire avec LINQ peut être fait à l'aide d'instructions SELECT, on ne peut pas en dire autant de l'inverse.
Rudey

3

Je sais que c'est une vieille question et il y a beaucoup de réponses ici, mais j'ai forcé à un problème lorsque j'utilise cette réponse et une erreur s'est produite lorsque j'utilise la commande update-database dans la console du gestionnaire de package:

Il existe déjà un objet nommé '...' dans la base de données.

et j'utilise ces étapes pour résoudre ce problème:

  1. exécutez cette commande dans la console du gestionnaire de package: Add-migration initial
  2. Dans le dossier Migrations, vous pouvez trouver le fichier ..._ intial.cs, l'ouvrir et commenter ou supprimer toute commande liée à votre classe que vous souhaitez mapper
  3. maintenant, vous pouvez normalement utiliser la commande update-database pour toute autre modification de vos modèles

J'espère que cela aide.


1
Merci! Cela a vraiment aidé! En supplément, au lieu de simplement supprimer le code généré avec EF Migrations, vous pouvez à la place y ajouter migrationBuilder.Sql("CREATE OR REPLACE VIEW ...); Pour que les collègues puissent également l'utiliser pour mettre à niveau leur base de données.
Rich_Rich
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.