web-dev-qa-db-fra.com

La base de données EF 6 en premier: comment mettre à jour les procédures stockées?

Nous utilisons Entity Framework 6.0.0 et utilisons d'abord la base de données (comme cela) } pour générer du code à partir de tables et de procédures stockées. Cela semble très bien fonctionner, sauf que les modifications apportées aux procédures stockées ne sont pas reflétées lors de la mise à jour ou de l'actualisation du modèle. L'ajout d'une colonne à une table est reflété, mais pas l'ajout d'un champ à une procédure stockée. 

Il est intéressant de noter que si je passe au Model Browser, cliquez avec le bouton droit de la souris sur la procédure stockée, sélectionnez Add Function Import et cliquez sur le bouton Get Column Information pour afficher les colonnes appropriées. Cela signifie que le modèle connaît des colonnes, mais ne parvient pas à mettre à jour le code généré.

Il existe une solution de contournement, à savoir la suppression de la procédure stockée générée avant la mise à jour du modèle. Cela fonctionne tant que vous n'avez apporté aucune modification à la procédure stockée. Est-ce que quelqu'un connaît un moyen d'éviter cette solution de contournement?

J'utilise Visual Studio 2013 avec toutes les dernières mises à jour à partir de début décembre 2013.

Merci d'avance!

Mise à jour 1: La réponse de Andersr a été utile dans un cas où la procédure stockée utilisait une table temporaire. Je lui ai donc donné +1, mais cela ne résout toujours pas le problème principal de la mise à jour de procédures stockées simples.

Mise à jour 2: Le commentaire de Shimron ci-dessous renvoie à une question sur les mêmes problèmes dans EF 3.5. Il semble que ce soit toujours le cas pour EF 6.0. Lisez-le pour une autre façon de le faire, mais ma conclusion est que le moyen le plus simple de le faire est de supprimer la procédure stockée générée avant de mettre à jour le modèle. Utilisez des classes partielles si vous voulez faire quelque chose d'extraordinaire.

43
Halvard

Basé sur cette réponse par DaveD , ces étapes permettent de résoudre le problème suivant:

  1. Dans votre .edmx, cliquez avec le bouton droit de la souris et sélectionnez Navigateur de modèles.
  2. Dans le navigateur de modèle (dans la configuration par défaut de VS 2015, il s'agit d'un onglet de l'explorateur de solutions), développez Function Imports sous le modèle.
  3. Double-cliquez sur votre procédure stockée.
  4. Cliquez sur le bouton Mettre à jour en regard de Retourne une collection de - Complexe (si vous ne retournez pas de scalaire ou d'entité).
  5. Cliquez sur okay puis sur save votre fichier .edmx pour refléter les modifications apportées aux champs dans votre procédure stockée tout au long de votre projet.
94
Rick V

Vos procédures stockées renvoient-elles des données de tables temporaires par hasard? EF ne semble pas supporter cela, voir EF4 - La procédure stockée sélectionnée ne renvoie aucune colonne pour plus d'informations.

Cependant, la procédure stockée sera, comme vous l'avez observé, disponible dans le Navigateur de modèles. J'ai fait un test rapide avec le scénario décrit ci-dessus. La procédure stockée a été générée dans ma classe de contexte, mais le type de retour était un int plutôt qu'un type complexe. Voir le lien ci-dessus pour des solutions de contournement potentielles.

2
andersr

Je viens de rencontrer ceci et ma solution de contournement (c'est vraiment désagréable) était de créer une instruction if avec une condition qui ne sera jamais vraie en haut de la procédure stockée, qui sélectionne la même liste de sorties que la requête avec transtypage explicite vers les types de données Je veux retourner. Cela supposera la nullité de vos types, donc résolvez de placer le casting dans une variable ISNULL

Par exemple, si votre sortie contient les colonnes:

UserId (int, not null)
RoleId (int, nullable)
FirstName (varchar(255), nullable)
Created (datetime, not null)

Vous vous attendez à ce que cela crée un POCO comme:

SomeClass {
    public int UserId { get; set; }
    public int? RoleId { get; set; }
    public string FirstName { get; set; }
    public DateTime Created { get; set; }
}

... Mais ce n'est pas le cas et c'est pourquoi nous sommes ici aujourd'hui. Pour résoudre ce problème et ne pas fonctionner comme prévu, j'ai placé ce qui suit en haut de mon SP (juste après le 'AS'):

if(1=0)
begin
    select
        UserId = isnull((cast(0 as int)),0),
        RoleId = cast(0 as int),
        FirstName = cast(0 as varchar),
        DateTime = isnull((cast(0 as datetime)),'')
end

C'est horrible et moche mais ça marche pour moi à chaque fois. J'espère que nous aurons une mise à jour de l'outillage qui résoudra cela bientôt ... m'est arrivée aujourd'hui sans tables temporaires dans SQL Server 2016 avec VS2015 ...

J'espère que ça aide quelqu'un

0
How 'bout a Fresca