ASP.NET MVC: najlepszy sposób wywołania procedury składowanej

Próbuję zdecydować, który jest najlepszym sposobem na wywołanie procedury składowanej.

I ' m new to ASP.NET MVC i czytałem dużo o Linq do SQL i Entity Framework, a także wzór repozytorium. Szczerze mówiąc, ciężko mi zrozumieć prawdziwe różnice między L2 i EF... ale chcę się upewnić, że to, co buduję w mojej aplikacji, jest właściwe.

Na razie muszę poprawnie wywołać procedury składowane, Aby: a) zapisać pewne informacje o użytkowniku i uzyskaj odpowiedź i b) Zdobądź informacje o katalogu produktów.

Do tej pory stworzyłem Linq do SQL .pliku dbml, wybrał procedurę sotred z Eksploratora serwera i przeciągnął tę instancję dodbml. Obecnie wywołuję procedurę składowaną w następujący sposób:

MyLinqModel _db = new MyLinqModel();
_db.MyStoredProcedure(args);
Wiem, że trzeba być bardziej zaangażowanym... plus robię to w ramach mojego kontrolera, co rozumiem, że nie jest dobrą praktyką. Czy ktoś może rozpoznać moje problemy?
Author: tereško, 2010-11-23

5 answers

LINQ i EF są prawdopodobnie przesadą, jeśli próbujesz tylko wywołać zapisany proc.

Używam Biblioteki Enterprise, ale ADO.NET będzie również działać dobrze.

Zobacz ten tutorial .

Krótko (bezwstydnie skopiowane i wklejone z przywołanego artykułu):

    SqlConnection conn = null;
    SqlDataReader rdr  = null;

    // typically obtained from user
    // input, but we take a short cut
    string custId = "FURIB";

    Console.WriteLine("\nCustomer Order History:\n");

        // create and open a connection object
        conn = new SqlConnection("Server=(local);DataBase=Northwind; Integrated Security=SSPI");
        conn.Open();

        // 1.  create a command object identifying
        //     the stored procedure
        SqlCommand cmd  = new SqlCommand(
            "CustOrderHist", conn);

        // 2. set the command object so it knows
        //    to execute a stored procedure
        cmd.CommandType = CommandType.StoredProcedure;

        // 3. add parameter to command, which
        //    will be passed to the stored procedure
        cmd.Parameters.Add(
            new SqlParameter("@CustomerID", custId));

        // execute the command
        rdr = cmd.ExecuteReader();

        // iterate through results, printing each to console
        while (rdr.Read())
        {
            Console.WriteLine(
                "Product: {0,-35} Total: {1,2}",
                rdr["ProductName"],
                rdr["Total"]);
        }
    }

Update

Przegapiłem część, w której powiedziałeś, że robisz to w swoim kontrolerze. Nie, to nie jest właściwy sposób.

Twój kontroler powinien tak naprawdę angażuj się tylko w koordynowanie budowy widoku. Utwórz oddzielną bibliotekę klas, zwaną "warstwą dostępu do danych" lub czymś mniej ogólnym, i utwórz klasę, która obsługuje wywoływanie przechowywanych proc, tworzenie obiektów z wyników, itp. Istnieje wiele opinii na temat tego, jak należy to zrobić, ale być może najbardziej powszechne jest:

View
|
Controller
|
Business Logic
|
Data Access Layer
   |--- SQL (Stored procs)
           -Tables
           -Views
           -etc.
   |--- Alternate data sources
           -Web services
           -Text/XML files
           -blah blah blah.

MSDN ma przyzwoity samouczek na ten temat.

 19
Author: 3Dave,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-23 22:38:15

Spróbuj tego:

Powinno być:

var authors = context.Database.SqlQuery<Author>("usp_GetAuthorByName @AuthorName", 
new SqlParameter("@AuthorName", "author"));

Aktualizacja:

var affectedRows = context.Database.ExecuteSqlCommand
("usp_CreateAuthor @AuthorName = {0}, @Email= {1}", 
"author", "email");

Z tego linku: http://www.dotnetthoughts.net/how-to-execute-a-stored-procedure-with-entity-framework-code-first/

I wybrałbym framework, o którym wspomniał David Lively, zamiast mieć procedury w kontrolerze. Po prostu przekaż wyniki jako IEnumerable<blah> z funkcji w oddzielnej klasie repozytorium dla edycji, przekaż wartość logiczną z powrotem, jeśli aktualizacja powiodła się dla aktualizacji.

 3
Author: vapcguy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-21 05:13:28

LINQ do SQL i ADO.NET EF załącz odczyt przechowywanych proc do klasy kontekstu danych / obiektów, której używasz do przeciwstawiania się jej różnym obiektom. W przypadku tworzenia, aktualizowania i usuwania można utworzyć proc, który mapuje właściwości encji generowanej przez model, a za pomocą okna mapowania encji (zapomnij teraz o dokładnej nazwie) można mapować pola encji z parametrami proc. Powiedzmy więc, że masz tabelę klientów, EF generuje jednostkę klientów i możesz mapować parametry proc do właściwości podmiotu Klienta podczas próby aktualizacji / Wstawienia/usunięcia.

Teraz możesz mapować CUD proc do funkcji, ale nie znam wszystkich reperkusji; najbardziej podoba mi się sposób, w jaki właśnie wspomniałem.

HTH.

 2
Author: Brian Mains,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-23 19:53:02

I wspólny wzorzec to przekazywanie interfejsu repozytorium do kontrolera przez wstrzyknięcie zależności. Wybór, jakiej technologii persistence / orm używasz, jest naprawdę innym problemem i nie ma związku z faktem, że używasz MVC. Wykorzystanie wzorca repozytorium i kodowanie do abstrakcji (interfejsów) sprawia, że aplikacja jest łatwa do przetestowania, wyśmiewając swoje repozytoria.

Myślę, że powinieneś również spróbować użyć jak najmniej procedur przechowywanych. Oznacza to, że można łatwiej przetestować swoje logika w izolacji (testy jednostkowe) bez konieczności podłączania do bazy danych. Gorąco polecam spojrzeć na NHibernate. Krzywa uczenia się jest dość stroma, ale masz pełną kontrolę nad mapowaniem i konfiguracją. Są oczywiście okazje, w których będziesz potrzebował przechowywanych proc ze względu na wydajność, ale używanie ORM jest głównie bardzo korzystne.

 -1
Author: Matt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-23 20:06:47

Nie wyobrażam sobie, żeby twoim celem było wywołanie procedury składowanej. Dla mnie brzmi to tak, jakbyś musiał zapomnieć o procedurach składowanych i użyć Linq do Sql. Mówię L2S, ponieważ EF jest znacznie więcej do nauczenia się, a nie potrzebne w tym przypadku.

 -5
Author: PDCBob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-23 21:15:10