Nieprzetworzone zapytania SQL (EF6)

Program Entity Framework umożliwia wykonywanie zapytań przy użyciu linQ z klasami jednostek. Może jednak wystąpić czas, w którym chcesz uruchamiać zapytania przy użyciu nieprzetworzonego kodu SQL bezpośrednio w bazie danych. Obejmuje to wywoływanie procedur składowanych, które mogą być przydatne w przypadku modeli Code First, które obecnie nie obsługują mapowania procedur składowanych. Techniki przedstawione w tym temacie dotyczą modeli utworzonych przy użyciu podejścia „najpierw kod” i narzędzia EF Designer.

Pisanie zapytań SQL dla jednostek

Metoda SqlQuery w zestawie DbSet umożliwia napisanie nieprzetworzonego zapytania SQL, które zwróci wystąpienia jednostek. Zwrócone obiekty będą śledzone przez kontekst tak, jak gdyby zostały zwrócone przez zapytanie LINQ. Przykład:

using (var context = new BloggingContext())
{
    var blogs = context.Blogs.SqlQuery("SELECT * FROM dbo.Blogs").ToList();
}

Należy pamiętać, że podobnie jak w przypadku zapytań LINQ zapytanie nie jest wykonywane, dopóki wyniki nie zostaną wyliczone — w powyższym przykładzie wykonano wywołanie metody ToList.

Należy zachować ostrożność za każdym razem, gdy nieprzetworzone zapytania SQL są zapisywane z dwóch powodów. Najpierw należy napisać zapytanie, aby upewnić się, że zwraca tylko jednostki, które są naprawdę żądanego typu. Na przykład w przypadku korzystania z funkcji, takich jak dziedziczenie, można łatwo napisać zapytanie, które utworzy jednostki o nieprawidłowym typie CLR.

Po drugie, niektóre typy nieprzetworzonych zapytań SQL ujawniają potencjalne zagrożenia bezpieczeństwa, zwłaszcza w przypadku ataków polegających na wstrzyknięciu kodu SQL. Upewnij się, że używasz parametrów w zapytaniu w prawidłowy sposób, aby chronić się przed takimi atakami.

Ładowanie jednostek z procedur składowanych

Aby załadować jednostki z wyników procedury składowanej, możesz użyć metody DbSet.SqlQuery. Na przykład poniższy kod wywołuje dbo. Procedura GetBlogs w bazie danych:

using (var context = new BloggingContext())
{
    var blogs = context.Blogs.SqlQuery("dbo.GetBlogs").ToList();
}

Parametry można również przekazać do procedury składowanej przy użyciu następującej składni:

using (var context = new BloggingContext())
{
    var blogId = 1;

    var blogs = context.Blogs.SqlQuery("dbo.GetBlogById @p0", blogId).Single();
}

Pisanie zapytań SQL dla typów innych niż jednostki

Zapytanie SQL zwracające wystąpienia dowolnego typu, w tym typy pierwotne, można utworzyć przy użyciu metody SqlQuery w klasie Database. Przykład:

using (var context = new BloggingContext())
{
    var blogNames = context.Database.SqlQuery<string>(
                       "SELECT Name FROM dbo.Blogs").ToList();
}

Wyniki zwrócone z zapytania SqlQuery w bazie danych nigdy nie będą śledzone przez kontekst, nawet jeśli obiekty są wystąpieniami typu jednostki.

Wysyłanie nieprzetworzonych poleceń do bazy danych

Polecenia inne niż zapytania można wysyłać do bazy danych przy użyciu metody ExecuteSqlCommand w bazie danych. Przykład:

using (var context = new BloggingContext())
{
    context.Database.ExecuteSqlCommand(
        "UPDATE dbo.Blogs SET Name = 'Another Name' WHERE BlogId = 1");
}

Należy pamiętać, że wszelkie zmiany wprowadzone w danych w bazie danych przy użyciu polecenia ExecuteSqlCommand są nieprzezroczyste do kontekstu, dopóki jednostki nie zostaną załadowane lub ponownie załadowane z bazy danych.

Parametry wyjściowe

Jeśli są używane parametry wyjściowe, ich wartości nie będą dostępne do czasu całkowitego odczytania wyników. Jest to spowodowane podstawowym zachowaniem elementu DbDataReader, zobacz Pobieranie danych przy użyciu elementu DataReader , aby uzyskać więcej szczegółów.