Unformatierte SQL-Abfragen (EF6)

Entity Framework ermöglicht Ihnen die Abfrage mittels LINQ mit Ihren Entitätsklassen. Es kann jedoch vorkommen, dass Sie Abfragen mit unformatierter SQL direkt gegen die Datenbank ausführen möchten. Dazu gehören das Aufrufen gespeicherter Prozeduren, was für Code First-Modelle hilfreich sein kann, die derzeit keine Zuordnung zu gespeicherten Prozeduren unterstützen. Die in diesem Thema dargestellten Techniken gelten jeweils für Modelle, die mit Code First und dem EF-Designer erstellt wurden.

Schreiben von SQL-Abfragen für Entitäten

Die SqlQuery-Methode für DbSet ermöglicht das Schreiben einer unformatierten SQL-Abfrage, die Entitätsinstanzen zurückgibt. Die zurückgegebenen Objekte werden vom Kontext genauso nachverfolgt, wie wenn sie durch eine LINQ-Abfrage zurückgegeben würden. Beispiel:

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

Beachten Sie, dass die Abfrage wie bei LINQ-Abfragen erst ausgeführt wird, wenn die Ergebnisse enumeriert werden – im obigen Beispiel geschieht dies mit dem Aufruf von ToList.

Bei der Erstellung von unformatierten SQL-Abfragen ist aus zwei Gründen Vorsicht geboten. Erstens sollte die Abfrage so geschrieben werden, dass sichergestellt ist, dass nur Entitäten zurückgegeben werden, die wirklich vom angeforderten Typ sind. Wenn Sie beispielsweise Features wie Vererbung verwenden, ist es einfach, eine Abfrage zu schreiben, die Entitäten des falschen CLR-Typs erstellt.

Zweitens legen einige Typen von unformatierten SQL-Abfragen potenzielle Sicherheitsrisiken offen, insbesondere bei Angriffen durch Einschleusung von SQL-Befehlen. Stellen Sie sicher, dass Sie Parameter in Ihrer Abfrage auf die richtige Weise verwenden, um vor solchen Angriffen zu schützen.

Laden von Entitäten aus gespeicherten Prozeduren

Sie können DbSet.SqlQuery verwenden, um Entitäten aus den Ergebnissen einer gespeicherten Prozedur zu laden. Der folgende Code ruft beispielsweise die dbo.GetBlogs-Prozedur in der Datenbank auf:

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

Sie können Parameter auch mithilfe der folgenden Syntax an eine gespeicherte Prozedur übergeben:

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

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

Schreiben von SQL-Abfragen für Nicht-Entitätstypen

Eine SQL-Abfrage, die Instanzen eines beliebigen Typs zurückgibt, einschließlich primitiver Typen, kann mithilfe der SqlQuery-Methode in der Datenbankklasse erstellt werden. Beispiel:

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

Die Ergebnisse, die von SqlQuery in der Datenbank zurückgegeben werden, werden niemals vom Kontext nachverfolgt, selbst wenn es sich bei den Objekten um Instanzen eines Entitätstyps handelt.

Senden von unformatierten Befehlen an die Datenbank

Nicht-Abfrage-Befehle können mithilfe der ExecuteSqlCommand-Methode in der Datenbank an die Datenbank gesendet werden. Beispiel:

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

Beachten Sie, dass alle Änderungen, die an Daten in der Datenbank mithilfe von ExecuteSqlCommand vorgenommen wurden, für den Kontext undurchsichtig sind, bis Entitäten aus der Datenbank geladen oder neu geladen werden.

Ausgabeparameter

Wenn Ausgabeparameter verwendet werden, sind ihre Werte erst verfügbar, wenn die Ergebnisse vollständig gelesen wurden. Dies liegt an dem zugrunde liegenden Verhalten von DbDataReader, weitere Details finden Sie unter Abrufen von Daten mithilfe eines DataReader.