2015-08-21 13 views
30

Sto cercando di ottenere il contenuto una tabella con una procedura SQL memorizzata dinamica chiamata dall'oggetto contesto del database (utilizzando Entity Framework 6.1.1), per popolare un controllo GridView. Non riesco a recuperare i dati.Ottenere dati dalla stored procedure con Entity Framework

Ecco la procedura memorizzata. È per una dimostrazione da parte degli studenti di SQL injection in stored procedure, quindi I KNOW è iniettabile e va bene.

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 

Il codice C# dietro Ho quindi utilizzare per eseguire la stored procedure è:

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

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

Quando viene eseguito, in Esplora database in Visual Studio, la stored procedure funziona bene. Ma quando viene eseguito nell'app ASP.NET in esecuzione, ottengo un'eccezione nel metodo DataBind() perché result restituisce -1 anziché IEnumerableDataSet contenente gli oggetti risultanti dal SELECT della procedura memorizzata.

Come posso recuperare i dati e compilare il mio GridView?

+0

In edmx, andare su Function Imports -> SearchProducts e fare doppio clic su di esso. A cosa è impostato il tipo di ritorno? – Vahlkron

+0

Il tipo di ritorno non è impostato. È (Nessuno). – mak

+0

Sembra che debba essere impostato su Complesso. L'unica cosa che potrei suggerire, dato che non ho avuto EF mi dà problemi quando lo faccio, cambia * per selezionare esplicitamente le colonne che vuoi nel SP. Forse EF la guarda per determinare il tuo tipo di ritorno. Quindi aggiorna il tuo EDMX in modo che le modifiche si riflettano in EF. – Vahlkron

risposta

27

utilizzare le seguenti operazioni per risolvere questo problema:

  1. è necessario importare la stored procedure come una funzione. Fare clic con il tasto destro del mouse sull'area di lavoro del modello Entity e selezionare Add -> Function Import.
  2. Nella finestra di dialogo Aggiungi funzione di importazione, immettere il nome al quale si desidera fare riferimento alla procedura memorizzata nel modello, ad esempio Search_Products, scegliere la procedura dall'elenco a discesa e scegliere il valore di ritorno della procedura da Entities e scegliere Products dall'elenco a discesa.
  3. Poi nel codice dietro:

    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 ragione per cui si ottiene -1 per il risultato è che Entity Framework non possono supportare Stored Valori Procedura per la restituzione, fuori dalla scatola. Penso che il supporto dei valori restituiti dalla stored procedure dipenda dalla versione del framework Entity. Anche Entity Framework non ha un ricco supporto per le stored procedure perché è un ORM, non una sostituzione SQL.

+4

Dolce madre di tutti i linguaggi di codice. Non ho alcuna idea folle del perché ora funzioni. Spero che questo rimanga stabile. Grazie x1000 amico. +100 reputazione meritata. – mak

0

Verificare che EDMX abbia un tipo restituito: Passare a Funzione Importazioni -> Cerca prodotti e fare doppio clic su di esso.

Per utilizzare un tipo di reso Complesso, Entity Framework richiede la definizione esplicita dei nomi di colonna nella stored procedure anziché l'utilizzo di *.

Dopo aver modificato la procedura memorizzata per definire i nomi delle colonne, è possibile aggiornare il modello nel progetto. (Si noti, l'esecuzione di una goccia completa del SP, e quindi aggiungendo di nuovo al vostro edmx può essere la strada migliore.)

EDIT

forse si può modificare la SP come la seguente:

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

Quando si tenta di aggiungere un tipo complesso a questa procedura memorizzata nel modello, model explorer non consente di aggiungerlo perché "la stored procedure selezionata non restituisce alcuna colonna" – mak

+0

È possibile modificarla come sopra o se si dispone di avere @query? .... con l'eccezione che dovresti dichiarare le tue colonne in modo specifico. – Vahlkron

+0

Quindi ... Funziona definendo il tipo di ritorno come entità di tipo "Prodotto". Ora quello che voglio è che il tipo restituito sia un tipo complesso, non un'entità. Imma prova quello che hai suggerito. Ad ogni modo, la tua soluzione ha aiutato, accetterò dopo i miei ultimi tentativi. – mak

3

Mi sono imbattuto in questo prima con stored procedure utilizzando SQL dinamico. Ho avuto successo usando tipi complessi se aggiungo la riga 'SET FMTONLY OFF;' (vedere https://msdn.microsoft.com/en-us/library/ms173839.aspx) all'inizio della procedura memorizzata prima che venga aggiunto al modello EF. Una volta che hai configurato il tuo modello con il tuo tipo complesso, assicurati di rimuovere questa linea.

Esempio:

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 
+0

Sì, ci ho provato, non mi ha aiutato. Ma l'ho trovato interessante perché mi ha fatto capire il funzionamento interno di EF e come ottiene i metadati per creare il set di risultati. – mak

0

Sembra che tu abbia ordinato il vostro problema fuori, non c'è documentazione ufficiale da Microsoft disponibili ai seguenti link:

come importare una stored procedure nel vostro modello di dati di entità: https://msdn.microsoft.com/en-us/library/vstudio/bb896231(v=vs.100).aspx

tipi complessi in progettista EF: https://msdn.microsoft.com/en-gb/data/jj680147.aspx

Assicurarsi di lavorare con la versione più recente di .net e mantenere aggiornato il modello quando si apportano modifiche al database.

Problemi correlati