Entity Framework 6では、次のコマンドを使用してデータベースで生のSQLクエリを実行できます。
IEnumerable<string> Contact.Database.SqlQuery<string>("SELECT a.title FROM a JOIN b ON b.Id = a.aId WHERE b.Status = 10");
新しいプロジェクトでは、Entity Framework Core 2.1を使用しようとしています。生のSQLクエリを実行する必要があります。グーグル検索中に、拡張子SqlQuery
がFromSql
に変更されたことがわかります。ただし、FromSql
はDbSet<>
にのみ存在し、DbContext.Database
には存在しません。
DbSet<>
の外でFromSql
を実行するにはどうすればよいですか?メソッドFromSql
はデータベースオブジェクトDbContext.Database.FromSql<>
に存在しません。
拡張機能SqlQueryがFromSqlに変更されたことがわかります
ただし、新しいFromSql
メソッドは、SqlQuery
よりもリストラティブです。そのメソッドの documentation は、次のようないくつかの制限があることを説明しています。
SQLクエリは、モデルの一部であるエンティティタイプを返すためにのみ使用できます。 生のSQLクエリからアドホックタイプを返すことを可能にする のバックログが強化されました。
SQLクエリは、エンティティまたはクエリタイプのすべてのプロパティのデータを返す必要があります。
[...]
そのため、使用しているSQLクエリは次のとおりです。
SELECT a.title FROM a JOIN b ON b.Id = a.aId WHERE b.Status = 10
ドキュメントにあるように、FromSql
はentityまたはクエリタイプでのみ使用できます。 SQLクエリは、モデルで定義されたエンティティのすべてのデータを返しませんが、エンティティの1列のみを返します。ちなみに、2018年5月7日以降にリリース候補版に含まれるEF Core 2.1に新しい機能が導入されました。Microsoftは次のように述べています。
EF Core 2.1 RC1は「Go Live」リリースです。つまり、アプリケーションがRC1で正常に動作することをテストしたら、本番環境で使用し、Microsoftからサポートを受けることができますが、利用可能になったら最終的な安定リリースに更新する必要があります。
クエリタイプ :とは
EF Coreモデルにクエリタイプを含めることができるようになりました。エンティティタイプとは異なり、クエリタイプにはキーが定義されておらず、挿入、削除、または更新できません(つまり、読み取り専用です)が、クエリから直接返すことができます。クエリタイプの使用シナリオには、主キーのないビューへのマッピング、主キーのないテーブルへのマッピング、モデルで定義されたクエリへのマッピング、FromSql()クエリの戻り値の型として機能するものがあります。
最初にクラスを定義するSQLテキストでクエリタイプ機能を使用する場合は、MySuperClass
という名前を付けましょう。
public class MySuperClass
{
public string Title { get; set; }
}
次に、DbContext
クラスで、以下のようにDbQuery<MySuperClass>
型のプロパティを定義しました。
public DbQuery<MySuperClass> MySuperQuery { get; set; }
最後に、以下のようにFromSql
を使用できます:
var result = context.MySuperQuery.FromSql("SELECT a.title FROM a JOIN b ON b.Id = a.aId WHERE b.Status = 10").ToList().First();
var title = result.Title;
DbQuery<T>
を使用したくないDbQuery<T>
を使用したくない場合、およびプロパティを1つだけ含むクラスを定義したくない場合は、@vivek nunaのようなExecuteSqlCommandAsync
を使用できます。 彼の答え(彼の答えは部分的に正しい)でした。ただし、そのメソッドから返される値がクエリの影響を受ける行の数であることを知っておく必要があります。また、クエリをストアドプロシージャにするために、タイトルを出力パラメーターとして配置する必要があります。 ExecuteSqlCommandAsync
またはExecuteSqlCommand
を使用し、その後、メソッドを呼び出すときに渡した出力パラメーターを読み取ります。
ストアドプロシージャを作成せずにExecuteSqlCommandAsync
またはExecuteSqlCommand
を使用しない簡単な方法は、次のコードです。
using (var context = new MyDbContext())
{
var conn = context.Database.GetDbConnection();
await conn.OpenAsync();
var command = conn.CreateCommand();
const string query = "SELECT a.title FROM a JOIN b ON b.Id = a.aId WHERE b.Status = 10";
command.CommandText = query;
var reader = await command.ExecuteReaderAsync();
while (await reader.ReadAsync())
{
var title = reader.GetString(0);
// Do whatever you want with title
}
}
このロジックを、SQLクエリを受信して必要なデータを返すヘルパーメソッドにすることができます。しかし、 Dapper.Net を使用することをお勧めします。上記のようにRAW SQLを簡単に処理し、smae接続をDbContext
と共有するのに役立つ多くのヘルパーメソッドが含まれています。
次の方法で、Microsoft.EntityFrameworkCore.Relational
AssemblyのExecuteSqlCommandAsync
クラスで定義されているRelationalDatabaseFacadeExtensions
メソッドを使用できます。
_databaseContext.Database.ExecuteSqlCommandAsync(<Your parameters>)