web-dev-qa-db-fra.com

Obtention de données à partir d'une procédure stockée avec Entity Framework

J'essaie d'obtenir le contenu d'une table avec une procédure stockée SQL dynamique appelée à partir de l'objet de contexte de base de données (en utilisant Entity Framework 6.1.1), afin de remplir un contrôle GridView. Je n'arrive pas à récupérer les données.

Voici la procédure stockée. C'est pour une démonstration des étudiants sur l'injection SQL dans les procédures stockées, donc JE SAIS c'est injectable et c'est très bien.

ALTER PROCEDURE dbo.SearchProducts
  @SearchTerm VARCHAR(max)
AS
BEGIN
  DECLARE @query VARCHAR(max)
  SET @query = 'SELECT * FROM dbo.Products WHERE Name LIKE ''%' + @SearchTerm + '%'''
  EXEC(@query)
END

Le code C # derrière j'utilise ensuite pour exécuter la procédure stockée est:

var db = new MyEntities();
var TEST_SEARCH_TERM = "product";
var result = db.SearchProducts(TEST_SEARCH_TERM);

MyGridView.DataSource = result;
MyGridView.DataBind();

Une fois exécutée, dans l'Explorateur de bases de données dans Visual Studio, la procédure stockée fonctionne correctement. Mais lorsqu'elle est exécutée dans l'application ASP.NET en cours d'exécution, j'obtiens une exception dans la méthode DataBind() car result renvoie -1 Au lieu d'un IEnumerableDataSet contenant les objets résultant du SELECT de la procédure stockée.

Comment puis-je récupérer les données et remplir mon GridView?

32
mak

Utilisez les étapes suivantes pour résoudre ce problème:

  1. Vous devez importer la procédure stockée en tant que fonction. Cliquez avec le bouton droit sur la zone d'espace de travail de votre modèle d'entité et choisissez Add -> Function Import.
  2. Dans la boîte de dialogue Ajouter une fonction d'importation, entrez le nom auquel vous souhaitez que votre procédure stockée soit référencée dans votre modèle, par exemple Search_Products, choisissez votre procédure dans la liste déroulante, puis choisissez la valeur de retour de la procédure à Entities et choisissez Products dans la liste déroulante.
  3. Puis dans le code derrière:

    var db = new MyEntities();
    var TEST_SEARCH_TERM = "product";
    var result = db.Search_Products(TEST_SEARCH_TERM);//Search_Products is the name that you specified in Function Import dialog
    
    MyGridView.DataSource = result;
    MyGridView.DataBind();
    

La raison pour laquelle vous obtenez -1 car le résultat est qu'Entity Framework ne peut pas prendre en charge les valeurs de retour de procédure stockée prédéfinies. Je pense que le support des valeurs de retour des procédures stockées dépend de la version du framework Entity. De plus, Entity Framework ne prend pas en charge les procédures stockées riches car c'est un ORM, pas un remplacement SQL.

30
Salah Akbari

J'ai rencontré cela auparavant avec des procédures stockées utilisant du SQL dynamique. J'ai réussi à utiliser des types complexes si j'ajoute la ligne "SET FMTONLY OFF;" (voir https://msdn.Microsoft.com/en-us/library/ms173839.aspx ) en haut de ma procédure stockée avant son ajout au modèle EF. Une fois que vous avez configuré votre modèle avec votre type complexe, assurez-vous de supprimer cette ligne.

Exemple:

ALTER PROCEDURE dbo.SearchProducts
  @SearchTerm VARCHAR(max)
AS
BEGIN
  SET FMTONLY OFF;
  DECLARE @query VARCHAR(max)
  SET @query = 'SELECT * FROM dbo.Products WHERE Name LIKE ''%' + @SearchTerm + '%'''
  EXEC(@query)
END
3
gotmilk13531

Vous semblez avoir résolu votre problème, il existe une documentation officielle de Microsoft disponible sur les liens ci-dessous:

Comment importer une procédure stockée dans votre modèle de données d'entité: https://msdn.Microsoft.com/en-us/library/vstudio/bb896231 (v = vs.100) .aspx

Types complexes dans le concepteur EF: https://msdn.Microsoft.com/en-gb/data/jj680147.aspx

Assurez-vous que vous travaillez avec la dernière version de .net et gardez votre modèle à jour lorsque vous apportez des modifications à votre base de données.

0
user1641172

Vérifiez que votre EDMX a un type de retour: allez dans Function Imports -> SearchProducts, et double-cliquez dessus.

Pour utiliser un type de retour complexe, Entity Framework vous demandera de définir explicitement les noms de colonnes dans votre procédure stockée au lieu d'utiliser *.

Une fois votre procédure stockée modifiée pour définir les noms de colonne, vous pouvez mettre à jour votre modèle dans le projet. (Remarque, effectuer une suppression complète du SP, puis l'ajouter à votre edmx peut être le meilleur itinéraire.)

MODIFIER

Vous pouvez peut-être modifier votre SP comme suit:

ALTER PROCEDURE dbo.SearchProducts
  @SearchTerm VARCHAR(max)
AS
BEGIN
  SELECT * FROM dbo.Products WHERE Name LIKE '%' + @SearchTerm + '%'
END
0
Vahlkron