生の SQL クエリ (EF6)Raw SQL Queries (EF6)

Entity Framework を使用すると、エンティティクラスで LINQ を使用してクエリを実行できます。Entity Framework allows you to query using LINQ with your entity classes. ただし、生の SQL を使用してデータベースに対して直接クエリを実行することが必要になる場合があります。However, there may be times that you want to run queries using raw SQL directly against the database. これにはストアドプロシージャの呼び出しが含まれます。これは、ストアドプロシージャへのマッピングを現在サポートしていない Code First モデルに役立ちます。This includes calling stored procedures, which can be helpful for Code First models that currently do not support mapping to stored procedures. このトピックで紹介するテクニックは、Code First および EF Designer で作成されたモデルに等しく使用できます。The techniques shown in this topic apply equally to models created with Code First and the EF Designer.

エンティティに対する SQL クエリの記述Writing SQL queries for entities

DbSet の SqlQuery メソッドを使用すると、エンティティインスタンスを返す生の SQL クエリを記述できます。The SqlQuery method on DbSet allows a raw SQL query to be written that will return entity instances. 返されたオブジェクトは、LINQ クエリによって返された場合と同様に、コンテキストによって追跡されます。The returned objects will be tracked by the context just as they would be if they were returned by a LINQ query. 次に例を示します。For example:

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

LINQ クエリの場合と同様に、クエリは結果が列挙されるまで実行されないことに注意してください。上記の例では、これは ToList の呼び出しを使用して行われます。Note that, just as for LINQ queries, the query is not executed until the results are enumerated—in the example above this is done with the call to ToList.

生の SQL クエリが2つの理由で書き込まれるたびに、注意が必要です。Care should be taken whenever raw SQL queries are written for two reasons. 最初に、要求された型のエンティティのみが返されるようにクエリを記述する必要があります。First, the query should be written to ensure that it only returns entities that are really of the requested type. たとえば、継承などの機能を使用する場合、誤った CLR 型のエンティティを作成するクエリを記述するのは簡単です。For example, when using features such as inheritance it is easy to write a query that will create entities that are of the wrong CLR type.

次に、一部の種類の未加工の SQL クエリは、特に SQL インジェクション攻撃に関連する潜在的なセキュリティリスクを露呈します。Second, some types of raw SQL query expose potential security risks, especially around SQL injection attacks. このような攻撃から保護するために、クエリでパラメーターを正しい方法で使用していることを確認してください。Make sure that you use parameters in your query in the correct way to guard against such attacks.

ストアドプロシージャからのエンティティの読み込みLoading entities from stored procedures

DbSet SqlQuery を使用して、ストアドプロシージャの結果からエンティティを読み込むことができます。You can use DbSet.SqlQuery to load entities from the results of a stored procedure. たとえば、次のコードは dbo を呼び出します。データベース内の GetBlogs プロシージャ:For example, the following code calls the dbo.GetBlogs procedure in the database:

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

次の構文を使用して、ストアドプロシージャにパラメーターを渡すこともできます。You can also pass parameters to a stored procedure using the following syntax:

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

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

非エンティティ型に対する SQL クエリの記述Writing SQL queries for non-entity types

プリミティブ型を含む任意の型のインスタンスを返す SQL クエリは、データベースクラスの SqlQuery メソッドを使用して作成できます。A SQL query returning instances of any type, including primitive types, can be created using the SqlQuery method on the Database class. 次に例を示します。For example:

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

オブジェクトがエンティティ型のインスタンスであっても、データベースに対して SqlQuery から返された結果はコンテキストによって追跡されません。The results returned from SqlQuery on Database will never be tracked by the context even if the objects are instances of an entity type.

生のコマンドをデータベースに送信するSending raw commands to the database

クエリ以外のコマンドは、データベースで ExecuteSqlCommand メソッドを使用してデータベースに送信できます。Non-query commands can be sent to the database using the ExecuteSqlCommand method on Database. 次に例を示します。For example:

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

ExecuteSqlCommand を使用してデータベース内のデータに加えられた変更は、エンティティがデータベースから読み込まれるか、データベースから再読み込みされるまでコンテキストに対して不透明になります。Note that any changes made to data in the database using ExecuteSqlCommand are opaque to the context until entities are loaded or reloaded from the database.

出力パラメーターOutput Parameters

出力パラメーターが使用されている場合、結果が完全に読み取られるまで、値は使用できません。If output parameters are used, their values will not be available until the results have been read completely. これは、DbDataReader の基になる動作に起因します。詳細については、「 DataReader を使用したデータの取得」を参照してください。This is due to the underlying behavior of DbDataReader, see Retrieving Data Using a DataReader for more details.