Zapytania SQL pierwotnychRaw SQL Queries

Entity Framework Core pozwala na liście rozwijanej raw kwerendy SQL podczas pracy z relacyjnej bazy danych.Entity Framework Core allows you to drop down to raw SQL queries when working with a relational database. Może to być przydatne, jeśli kwerenda, którą chcesz wykonać, nie można wyrazić za pomocą LINQ lub za pomocą zapytań LINQ wynikiem jest nieefektywne SQL wysyłane do bazy danych.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.

Porada

Można wyświetlić w tym artykule próbki w witrynie GitHub.You can view this article's sample on GitHub.

OgraniczeniaLimitations

Istnieje kilka pod uwagę podczas korzystania z pierwotnych zapytania SQL następujące ograniczenia:There are a couple of limitations to be aware of when using raw SQL queries:

  • Zapytania SQL mogą służyć tylko do zwracanych typów jednostki, które są częścią modelu.SQL queries can only be used to return entity types that are part of your model. Brak ulepszeniem na naszych zaległości do Włącz zwracanie typy ad hoc z pierwotnych zapytania SQL.There is an enhancement on our backlog to enable returning ad-hoc types from raw SQL queries.

  • Zapytanie SQL musi zwracać dane dla wszystkich właściwości typu jednostki.The SQL query must return data for all properties of the entity type.

  • Nazwy kolumn w zestawie wyników muszą być zgodne nazwy kolumn, które są mapowane właściwości.The column names in the result set must match the column names that properties are mapped to. Należy zauważyć, że ta różni się od EF6 gdzie mapowania właściwości/kolumn została zignorowana dla nieprzetworzonej zapytania SQL i nazw musiały być zgodne z nazwami właściwości kolumny zestawu wyników.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.

  • Zapytania SQL nie może zawierać powiązanych danych.The SQL query cannot contain related data. Jednak w wielu przypadkach można utworzyć na podstawie zapytania za pomocą Include operatora, aby zwrócić dane dotyczące (zobacz powiązanych danych w tym).However, in many cases you can compose on top of the query using the Include operator to return related data (see Including related data).

Podstawowe raw zapytania SQLBasic raw SQL queries

Można użyć FromSql — metoda rozszerzenia, aby rozpocząć zapytania LINQ na podstawie pierwotnych zapytania SQL.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();

Nieprzetworzona zapytania SQL może służyć do wykonywania procedury składowanej.Raw SQL queries can be used to execute a stored procedure.

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

Przekazywanie parametrówPassing parameters

Podobnie jak w przypadku jakiegokolwiek interfejsu API, który akceptuje SQL, koniecznie parametryzacja wszystkie dane wejściowe użytkownika mają ochrony przed atakiem iniekcji kodu SQL.As with any API that accepts SQL, it is important to parameterize any user input to protect against a SQL injection attack. Może zawierać parametru symbole zastępcze w ciągu zapytania SQL, a następnie podaj wartości parametrów jako dodatkowe argumenty.You can include parameter placeholders in the SQL query string and then supply parameter values as additional arguments. Należy podać wartości parametrów zostaną automatycznie przekonwertowane na DbParameter.Any parameter values you supply will automatically be converted to a DbParameter.

Poniższy przykład przekazuje jeden parametr do procedury składowanej.The following example passes a single parameter to a stored procedure. Gdy wygląda jak String.Format składni, podana wartość jest ujęte w where dodaje parametr i nazwę parametru wygenerowanego {0} symbol zastępczy został określony.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();

Jest to ten sam zapytania, ale przy użyciu składni interpolacji ciąg, który jest obsługiwany w programie EF Core 2.0 i nowszych wersjach: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();

Można również utworzyć DbParameter i podać go jako wartości parametru.You can also construct a DbParameter and supply it as a parameter value. Dzięki temu można używać parametrów nazwanych w ciągu zapytania SQLThis 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();

Tworzenie za pomocą LINQComposing with LINQ

Jeśli zapytanie SQL mogą być składane na w bazie danych, można utworzyć na podstawie początkowego raw zapytania SQL przy użyciu operatorów LINQ.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. Zapytania SQL, które mogą być składane z tego z SELECT — słowo kluczowe.SQL queries that can be composed on being with the SELECT keyword.

W poniższym przykładzie użyto raw zapytanie SQL, który wybiera z funkcji zwracającej tabelę (TVF), a następnie Redaguj na nim za pomocą LINQ, aby wykonać filtrowanie i sortowanie.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();

Tworzenie przy użyciu operatorów LINQ może służyć do uwzględnienia powiązanych danych w zapytaniu.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();

Ostrzeżenie

Zawsze używaj parametryzacja raw kwerendy SQL: interfejsów API, które akceptuje raw SQL string, takich jak FromSql i ExecuteSqlCommand zezwalają na wartości, które mają być łatwo przekazane jako parametry.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. Oprócz sprawdzania poprawności danych wejściowych użytkownika, należy zawsze używać parametryzacja dla każdej wartości nieprzetworzonej zapytania SQL/polecenia.In addition to validating user input, always use parameterization for any values used in a raw SQL query/command. Jeśli używasz ciągów dynamicznie tworzenie dowolną część ciągu zapytania, a następnie jest odpowiedzialny za sprawdzanie poprawności żadnych danych do ochrony przez atakami iniekcji kodu SQL.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.