2015-08-21 17 views
30

Próbuję uzyskać zawartość tabeli z dynamiczną procedurą składowania SQL wywoływaną z obiektu kontekstowego bazy danych (przy użyciu Entity Framework 6.1.1) w celu zapełnienia formantu GridView. Nie mogę odzyskać danych.Pobieranie danych z procedury składowanej za pomocą Entity Framework

Oto procedura składowana. Jest to pokaz dla studentów na temat iniekcji SQL w procedurach przechowywanych, więc można go wstrzykiwać i jest w porządku.

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 

kod C# za I wtedy użyć do wykonania procedury przechowywanej jest:

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

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

Kiedy wykonywany w Eksploratorze bazy danych w Visual Studio, procedura przechowywana działa dobrze. Ale po uruchomieniu w uruchomionej aplikacji ASP.NET otrzymuję wyjątek w metodzie DataBind(), ponieważ result zwraca -1 zamiast z obiektu DataSet zawierającego obiekty wynikłe z SELECT składowanej procedury.

Jak mogę odzyskać dane i wypełnić moją GridView?

+0

W pliku edmx przejdź do Import funkcji -> Wyszukaj produkty i kliknij go dwukrotnie. Do czego jest ustawiony typ zwrotu? – Vahlkron

+0

Typ powrotu nie jest ustawiony. Jest (brak). – mak

+0

Wygląda na to, że musi być ustawiony jako Complex. Jedyna rzecz, którą mógłbym zasugerować, ponieważ nie miałem EF, sprawiało mi problemy, gdy robię to, zmień *, aby wyraźnie wybrać kolumny, które chcesz w SP. Może EF przyjrzy się temu, aby określić twój typ zwrotu. Następnie zaktualizuj edytor EDMX, aby zmiany zostały odzwierciedlone w EF. – Vahlkron

Odpowiedz

27

należy wykonać następujące kroki, aby rozwiązać ten problem:

  1. należy zaimportować procedury przechowywanej jako funkcja. Kliknij prawym przyciskiem myszy obszar obszaru roboczego swojego modelu jednostki i wybierz opcję Add -> Function Import.
  2. W oknie dialogowym Dodawanie funkcji należy podać nazwę modelu w swoim modelu, na przykład Search_Products, wybrać procedurę z listy rozwijanej i wybrać wartość zwracaną procedury, która ma być Entities i wybierz Products z rozwijanej listy.
  3. Następnie w kodzie za:

    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(); 
    

Powodem że masz -1 dla wyniku jest to, że Entity Framework nie obsługuje procedury przechowywanej wartości zwracane po wyjęciu z pudełka. Myślę, że obsługa zwracanych wartości procedury przechowywanej zależy od wersji struktury Entity. Również Entity Framework nie ma bogatej obsługi procedur składowanych, ponieważ jest to ORM, a nie zamiennik SQL.

+4

Słodka matka wszystkich języków kodowych. Nie mam zielonego pojęcia, dlaczego teraz działa. Mam nadzieję, że to pozostanie stabilne. Dzięki, koleś x1000. + 100 punktów na zasłużoną reputację. – mak

0

Sprawdź, czy twój EDMX ma typ zwrotu: Przejdź do importu funkcji -> SzukajProducts i kliknij go dwukrotnie.

Aby użyć złożonego typu zwracanego, struktura Entity będzie wymagać jawnego zdefiniowania nazw kolumn w przechowywanej procedurze zamiast użycia *.

Po zmodyfikowaniu procedury składowanej w celu zdefiniowania nazw kolumn można zaktualizować model w projekcie. (Uwaga, wykonując pełną kroplę SP, a następnie dodanie go do swojej edmx może być najlepsza droga.)

EDIT

Może modyfikować SP jak następuje:

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

Podczas próby dodania typu złożonego do tej procedury przechowywanej w modelu, eksplorator modelu nie pozwala na dodanie go, ponieważ "wybrana procedura składowana nie zwraca żadnej kolumny" – mak

+0

Czy możesz zmodyfikować to tak jak powyżej, lub czy masz mieć @query? .... z wyjątkiem tego, że powinieneś zadeklarować swoje kolumny w sposób konkretny. – Vahlkron

+0

Więc ... Gotowy do pracy, definiując typ zwrotu jako encję typu "Produkt". Teraz chcę, aby typ zwracany był złożonym typem, a nie jednostką. Imma spróbuj tego, co sugerujesz. W każdym razie Twoje rozwiązanie pomogło, zaakceptuję po moich ostatnich próbach. – mak

3

Natknąłem się na to wcześniej z procedurami przechowywanymi za pomocą dynamicznego SQL. Miałem powodzenie przy użyciu złożonych typów, jeśli dodaję linię "SET FMTONLY OFF"; (patrz https://msdn.microsoft.com/en-us/library/ms173839.aspx) na początek mojej procedury składowanej, zanim zostanie dodany do modelu EF. Po skonfigurowaniu modelu ze złożonym typem, pamiętaj o usunięciu tego wiersza.

Przykład:

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

Tak, spróbowałem, nie pomogło mi. Ale uznałem, że jest to interesujące, ponieważ pozwoliło mi zrozumieć działanie EF i dowiedzieć się, jak zdobywa metadane, aby zbudować zestaw wyników. – mak

Powiązane problemy