RAW-SQL-AbfragenRaw SQL Queries

Entity Framework Core können Sie SQL-Abfragen, die unformatierten Dropdown, bei der Arbeit mit einer relationalen Datenbank.Entity Framework Core allows you to drop down to raw SQL queries when working with a relational database. Dies kann nützlich sein, wenn die Abfrage, die Sie ausführen möchten mit LINQ ausgedrückt werden kann, oder wenn eine LINQ-Abfrage mit keine ineffizienten SQL, die an die Datenbank dazu führte, ist.This can be useful if the query you want to perform can't be expressed using LINQ, or if using a LINQ query is resulting in inefficient SQL being sent to the database.

Tipp

Sie können anzeigen, dass dieser Artikel Beispiel auf GitHub.You can view this article's sample on GitHub.

EinschränkungenLimitations

Es gibt einige Einschränkungen bei Verwendung von SQL-Abfragen, die unformatierte geachtet werden:There are a couple of limitations to be aware of when using raw SQL queries:

  • SQL-Abfragen können nur auf Entitätstypen zurückgeben, die Teil des Modells verwendet werden.SQL queries can only be used to return entity types that are part of your model. Es ist eine Erweiterung auf unseren nachholbedarf zu aktivieren, die Ad-hoc-Typen von unformatierten SQL-Abfragen zurückgeben.There is an enhancement on our backlog to enable returning ad-hoc types from raw SQL queries.

  • Die SQL-Abfrage muss es sich um Daten für alle Eigenschaften des Entitätstyps zurückgeben.The SQL query must return data for all properties of the entity type.

  • Die Spaltennamen im Resultset müssen die Spaltennamen entsprechen, denen Eigenschaften zugeordnet werden.The column names in the result set must match the column names that properties are mapped to. Beachten Sie, dass dieser vom EF6 unterscheidet, in denen Eigenschaft/spaltenzuordnung für unformatierte SQL-Abfragen wurde ignoriert, und Resultsetspalte mussten Namen der Eigenschaft entsprechen.Note this is different from EF6 where property/column mapping was ignored for raw SQL queries and result set column names had to match the property names.

  • Die SQL-Abfrage kann nicht verknüpfte Daten enthalten.The SQL query cannot contain related data. Allerdings in vielen Fällen machen Sie auf die Abfrage mithilfe der Include Operator, um verwandte Daten zurückzugeben (finden Sie unter einschließlich der zugehörige Daten).However, in many cases you can compose on top of the query using the Include operator to return related data (see Including related data).

Grundlegende unformatierten SQL-AbfragenBasic raw SQL queries

Sie können die FromSql Erweiterungsmethode, um eine LINQ-Abfrage basierend auf einer unformatierten SQL-Abfrage zu beginnen.You can use the FromSql extension method to begin a LINQ query based on a raw SQL query.

var blogs = context.Blogs
    .FromSql("SELECT * FROM dbo.Blogs")
    .ToList();

RAW-SQL-Abfragen können zum Ausführen einer gespeicherten Prozedur verwendet werden.Raw SQL queries can be used to execute a stored procedure.

var blogs = context.Blogs
    .FromSql("EXECUTE dbo.GetMostPopularBlogs")
    .ToList();

Übergeben von ParameternPassing parameters

Wie bei jeder API, die SQL akzeptiert, ist es wichtig, die zum Schutz vor SQL Injection-Angriff Eingabe durch den Benutzer zu parametrisieren.As with any API that accepts SQL, it is important to parameterize any user input to protect against a SQL injection attack. Sie können Platzhalter für Parameter in der SQL-Abfragezeichenfolge enthalten, und geben Sie dann Parameterwerte als zusätzliche Argumente.You can include parameter placeholders in the SQL query string and then supply parameter values as additional arguments. Alle Parameterwerte, die Sie angeben, werden automatisch konvertiert werden, um eine DbParameter.Any parameter values you supply will automatically be converted to a DbParameter.

Das folgende Beispiel übergibt einen einzelnen Parameter an eine gespeicherte Prozedur.The following example passes a single parameter to a stored procedure. Während dies aussehen könnte z. B. String.Format -Syntax wird der angegebene Wert in umschlossen Parameter und den generierten Parameternamen eingefügt Where der {0} Platzhalter angegeben wurde.While this may look like String.Format syntax, the supplied value is wrapped in a parameter and the generated parameter name inserted where the {0} placeholder was specified.

var user = "johndoe";

var blogs = context.Blogs
    .FromSql("EXECUTE dbo.GetMostPopularBlogsForUser {0}", user)
    .ToList();

Dies ist die gleiche Abfrage jedoch mit einer Zeichenfolge Interpolation Syntax in EF Core 2.0 und höher unterstützt wird:This is the same query but using string interpolation syntax, which is supported in EF Core 2.0 and above:

var user = "johndoe";

var blogs = context.Blogs
    .FromSql($"EXECUTE dbo.GetMostPopularBlogsForUser {user}")
    .ToList();

Sie können auch ein DbParameter-Objekt zu erstellen und als Parameterwert angeben.You can also construct a DbParameter and supply it as a parameter value. Dadurch können Sie benannte Parameter in der SQL-Abfragezeichenfolge verwendet werden.This allows you to use named parameters in the SQL query string

var user = new SqlParameter("user", "johndoe");

var blogs = context.Blogs
    .FromSql("EXECUTE dbo.GetMostPopularBlogsForUser @user", user)
    .ToList();

Verfassen von LINQComposing with LINQ

Wenn die SQL-Abfrage auf die Datenbank geschrieben werden kann, können Sie zusätzlich zu den anfänglichen raw SQL-Abfrage, die mithilfe von LINQ-Operatoren zusammenstellen.If the SQL query can be composed on in the database, then you can compose on top of the initial raw SQL query using LINQ operators. SQL-Abfragen, die zusammengesetzt werden können, auf die mit dem SELECT Schlüsselwort.SQL queries that can be composed on being with the SELECT keyword.

Im folgenden Beispiel wird eine unformatierte SQL-Abfrage, die aus einem Tabellenwertparameter-Funktion (TVF) Wählt aus, und klicken Sie dann verfasst darauf verwenden LINQ zum Ausführen von Filtern und sortieren.The following example uses a raw SQL query that selects from a Table-Valued Function (TVF) and then composes on it using LINQ to perform filtering and sorting.

var searchTerm = ".NET";

var blogs = context.Blogs
    .FromSql($"SELECT * FROM dbo.SearchBlogs({searchTerm})")
    .Where(b => b.Rating > 3)
    .OrderByDescending(b => b.Rating)
    .ToList();

Verfassen von LINQ-Operatoren kann verwendet werden, um verwandte Daten in der Abfrage enthalten.Composing with LINQ operators can be used to include related data in the query.

var searchTerm = ".NET";

var blogs = context.Blogs
    .FromSql($"SELECT * FROM dbo.SearchBlogs({searchTerm})")
    .Include(b => b.Posts)
    .ToList();

Warnung

Verwenden Sie immer die Parametrisierung für unformatierte SQL-Abfragen: APIs, die eine unformatierte SQL akzeptieren eine Zeichenfolge wie z. B. FromSql und ExecuteSqlCommand ermöglicht, dass Werte einfach als Parameter übergeben werden.Always use parameterization for raw SQL queries: APIs that accept a raw SQL string such as FromSql and ExecuteSqlCommand allow values to be easily passed as parameters. Zusätzlich zum Validieren von Benutzereingaben, verwenden Sie immer Parametrisierung für eine beliebige Werte, die in einem unformatierten SQL-Abfrage/Befehl verwendet.In addition to validating user input, always use parameterization for any values used in a raw SQL query/command. Wenn Sie einen beliebigen Teil der Abfragezeichenfolge dynamisch zu erstellen, dann sind Sie verantwortlich für das Validieren von Eingaben zum Schutz vor SQL Injection-Angriffen Verketten von Zeichenfolgen verwenden.If you are using string concatenation to dynamically build any part of the query string then you are responsible for validating any input to protect against SQL injection attacks.