次の方法で共有


生 SQL クエリ (EF6)

Entity Framework を使用すると、エンティティ クラスで LINQ を使用してクエリを実行できます。 ただし、データベースに対して直接生の SQL を使用してクエリを実行する必要がある場合があります。 これにはストアド プロシージャの呼び出しが含まれます。これは、現在ストアド プロシージャへのマッピングをサポートしていない Code First モデルに役立ちます。 このトピックで示す手法は、Code First と EF Designer で作成されたモデルにも同様に適用されます。

エンティティの SQL クエリの記述

DbSet の SqlQuery メソッドを使用すると、エンティティ インスタンスを返す生の SQL クエリを記述できます。 返されたオブジェクトは、LINQ クエリによって返された場合と同様に、コンテキストによって追跡されます。 例えば次が挙げられます。

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

LINQ クエリの場合と同様に、クエリは結果が列挙されるまで実行されません。上記の例では、ToList の呼び出しで実行されます。

生の SQL クエリが書き込まれるときは必ず、2 つの理由から注意する必要があります。 最初に、要求された型のエンティティのみが返されるように、クエリを記述する必要があります。 たとえば、継承などの機能を使用する場合、間違った CLR 型のエンティティを作成するクエリを簡単に記述できます。

第 2 に、一部の種類の生 SQL クエリでは、特に SQL インジェクション攻撃に関する潜在的なセキュリティ リスクが明らかにされます。 このような攻撃から保護する正しい方法で、クエリでパラメーターを使用していることを確認します。

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

DbSet.SqlQuery を使用して、ストアド プロシージャの結果からエンティティを読み込むことができます。 たとえば、次のコードはデータベースにある dbo.GetBlogs ストアド プロシージャを呼び出します。

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

次の構文を使用して、ストアド プロシージャにパラメーターを渡すこともできます。

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

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

非エンティティ型の SQL クエリの記述

プリミティブ型を含む任意の型のインスタンスを返す SQL クエリは、Database クラスの SqlQuery メソッドを使用して作成できます。 例えば次が挙げられます。

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

SqlQuery on Database から返される結果は、オブジェクトがエンティティ型のインスタンスであっても、コンテキストによって追跡されることはありません。

未加工のコマンドをデータベースに送信する

クエリ以外のコマンドは、データベースの ExecuteSqlCommand メソッドを使用してデータベースに送信できます。 例えば次が挙げられます。

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

ExecuteSqlCommand を使用してデータベース内のデータに加えられた変更は、エンティティがデータベースに読み込まれるか、データベースから再読み込みされるまで、コンテキストに対して不透明であることに注意してください。

出力パラメーター

出力パラメーターを使用する場合、結果が完全に読み取られるまで、その値は使用できません。 これは、DbDataReader の基になる動作が原因です。詳細については、「 DataReader を使用したデータの取得 」を参照してください。