Nezpracované dotazy SQL (EF6)

Entity Framework umožňuje dotazování pomocí LINQ s třídami entit. Někdy ale můžete chtít spouštět dotazy pomocí nezpracovaného SQL přímo s databází. To zahrnuje volání uložených procedur, které můžou být užitečné pro modely Code First, které aktuálně nepodporují mapování na uložené procedury. Techniky uvedené v tomto tématu jsou rovnocenné pro modely vytvořené pomocí Code First a EF Designeru.

Psaní dotazů SQL pro entity

Metoda SqlQuery v DbSet umožňuje zápis nezpracovaného dotazu SQL, který vrátí instance entit. Vrácené objekty budou sledovány kontextem stejně jako kdyby byly vráceny dotazem LINQ. Příklad:

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

Všimněte si, že stejně jako u dotazů LINQ se dotaz nespustí, dokud se výsledky nevyčtou – v příkladu výše se provádí voláním ToList.

Při zápisu nezpracovaných dotazů SQL je potřeba věnovat pozornost dvěma důvodům. Nejprve by se měl dotaz zapsat, aby se zajistilo, že vrátí pouze entity, které jsou skutečně požadovaného typu. Například při použití funkcí, jako je dědičnost, je snadné napsat dotaz, který vytvoří entity, které jsou nesprávného typu CLR.

Za druhé, některé typy nezpracovaných dotazů SQL zpřístupňují potenciální bezpečnostní rizika, zejména v případě útoků prostřednictvím injektáže SQL. Ujistěte se, že ve svém dotazu používáte parametry správným způsobem, jak tyto útoky chránit.

Načítání entit z uložených procedur

Pomocí DbSet.SqlQuery můžete načíst entity z výsledků uložené procedury. Například následující kód volá dbo. Procedura GetBlogs v databázi:

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

Parametry můžete také předat uložené proceduře pomocí následující syntaxe:

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

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

Psaní dotazů SQL pro jiné typy než entity

Dotaz SQL vracející instance libovolného typu, včetně primitivních typů, lze vytvořit pomocí metody SqlQuery ve třídě Database. Příklad:

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

Výsledky vrácené z SqlQuery ve službě Database nebudou nikdy sledovány kontextem, a to ani v případě, že objekty jsou instancemi typu entity.

Odesílání nezpracovaných příkazů do databáze

Příkazy bez dotazu je možné odeslat do databáze pomocí metody ExecuteSqlCommand ve službě Database. Příklad:

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

Všimněte si, že všechny změny dat v databázi pomocí ExecuteSqlCommand jsou neprůžné pro kontext, dokud se entity nenačtou nebo znovu nenačtou z databáze.

Výstupní parametry

Pokud se použijí výstupní parametry, nebudou jejich hodnoty dostupné, dokud se výsledky nepřečtou úplně. Důvodem je základní chování DbDataReader, viz Načítání dat pomocí DataReader další podrobnosti.