生の SQL クエリRaw SQL Queries

Entity Framework Core では、リレーショナル データベースを使用する場合、生の SQL クエリをドロップ ダウンすることができます。Entity Framework Core allows you to drop down to raw SQL queries when working with a relational database. 実行するクエリは、LINQ を使用して表現できない場合、またはデータベースに送信される非効率的な SQL での LINQ クエリを使用するが結果として得られる場合、これは役立つあります。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.

ヒント

この記事を表示するサンプルGitHub でします。You can view this article's sample on GitHub.

制限事項Limitations

いくつかのような制限の生の SQL クエリを使用する場合があります。There are a couple of limitations to be aware of when using raw SQL queries:

  • SQL クエリは、モデルの一部であるエンティティ型を返すにのみ使用できます。SQL queries can only be used to return entity types that are part of your model. バックログに機能強化が生の SQL クエリからアドホック型を返す有効です。There is an enhancement on our backlog to enable returning ad-hoc types from raw SQL queries.

  • SQL クエリでは、エンティティ型のすべてのプロパティのデータを返す必要があります。The SQL query must return data for all properties of the entity type.

  • 結果セット内の列名は、プロパティにマップする列名と一致する必要があります。The column names in the result set must match the column names that properties are mapped to. これとは異なる SQL クエリの生のプロパティ/列マッピングは無視されました、結果セット列名は、プロパティの名前と一致する必要がある EF6 に注意してください。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.

  • SQL クエリでは、関連するデータを含めることはできません。The SQL query cannot contain related data. ただし、多くの場合を組み込むことができますを使用して、クエリの上に、Include関連データを返す演算子 (を参照してください関連データを含む)。However, in many cases you can compose on top of the query using the Include operator to return related data (see Including related data).

基本的な生 SQL クエリBasic raw SQL queries

使用することができます、 FromSql生 SQL クエリに基づく LINQ クエリを開始する拡張メソッド。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();

生の SQL クエリは、ストアド プロシージャの実行に使用できます。Raw SQL queries can be used to execute a stored procedure.

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

パラメーターを渡すPassing parameters

SQL を受け入れる任意の API と同様には、ユーザーの SQL インジェクション攻撃を防ぐために入力をパラメーター化する必要があります。As with any API that accepts SQL, it is important to parameterize any user input to protect against a SQL injection attack. SQL クエリ文字列にパラメーターのプレース ホルダーを含めるし、追加の引数とパラメーター値を指定できます。You can include parameter placeholders in the SQL query string and then supply parameter values as additional arguments. 指定するパラメーター値が自動的に変換する、DbParameterです。Any parameter values you supply will automatically be converted to a DbParameter.

次の例では、1 つのパラメーターをストアド プロシージャに渡します。The following example passes a single parameter to a stored procedure. 同様に見えるかもしれませんがこのString.Format構文に指定された値がラップされてパラメーターと、生成されたパラメーター名は、where を挿入、{0}プレース ホルダーを指定します。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();

これは、同じクエリが EF コア 2.0 以降がサポートされている文字列の補間の構文を使用しています。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();

また、DbParameter を構築し、パラメーター値として指定できます。You can also construct a DbParameter and supply it as a parameter value. これにより、SQL クエリ文字列の名前付きパラメーターを使用するには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();

LINQ で構成します。Composing with LINQ

場合は、データベース内の SQL クエリを組み込むことのできる、LINQ の演算子を使用して最初の生の SQL クエリの上に作成することができます。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 クエリの中で構成できる、SELECTキーワード。SQL queries that can be composed on being with the SELECT keyword.

次の例では、LINQ を使用してフィルター処理および並べ替えを実行することでから、テーブル値関数 (TVF) を選択し、合成を生 SQL クエリを使用します。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();

クエリに関連するデータを含める LINQ 演算子を含む構成を使用できます。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();

警告

常に生の SQL クエリをパラメーター化を使用:生 SQL を受け取る Api に文字列などFromSqlExecuteSqlCommandパラメーターとして簡単に渡される値を許可します。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. ユーザーの入力だけでなく、常に生 SQL クエリ/コマンドで使用される任意の値のパラメーター化を使用します。In addition to validating user input, always use parameterization for any values used in a raw SQL query/command. 使用している文字列の連結するには、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.