EFコアクエリからSQLコードを取得する

entity-framework-core

質問

私はEntity Framework 7 Core RC2 (EF Coreに改名)を使用しており、どのSQLコードが生成されているかを確認する必要があります。 Entity Frameworkの以前のバージョンでは、以下を使用できました:

String sql = ((System.Data.Objects.ObjectQuery)query).ToTraceString();

クエリはIQueryableオブジェクトですが、ToTraceStringはEFコアでは使用できません。

EFコアでも同様のことをどうすればできますか?

人気のある回答

EF 7はEntity Framework Coreに改名されたので、EF Coreのオプションについてまとめます。

IQueryable<>からSQL文をログに記録する方法は3つあります。

  • 組み込みまたはカスタムのログ記録を使用するこのチュートリアルで説明しているように、選択したロガーまたは.NET Coreの組み込みロガーを使用して実行中のクエリをログに記録します。
  • プロファイラーの使用MiniProfilerのようなSQLプロファイラを使って実行中のクエリを監視する。
  • クレイジーリフレクションコードを使う同じ基本概念を実行するために、以前の方法と同様のカスタムリフレクションコードを実装できます。

これがクレイジーリフレクションコード(拡張メソッド)です。

public static class IQueryableExtensions
{
    private static readonly TypeInfo QueryCompilerTypeInfo = typeof(QueryCompiler).GetTypeInfo();

    private static readonly FieldInfo QueryCompilerField = typeof(EntityQueryProvider).GetTypeInfo().DeclaredFields.First(x => x.Name == "_queryCompiler");

    private static readonly FieldInfo QueryModelGeneratorField = QueryCompilerTypeInfo.DeclaredFields.First(x => x.Name == "_queryModelGenerator");

    private static readonly FieldInfo DataBaseField = QueryCompilerTypeInfo.DeclaredFields.Single(x => x.Name == "_database");

    private static readonly PropertyInfo DatabaseDependenciesField = typeof(Database).GetTypeInfo().DeclaredProperties.Single(x => x.Name == "Dependencies");

    public static string ToSql<TEntity>(this IQueryable<TEntity> query) where TEntity : class
    {
        var queryCompiler = (QueryCompiler)QueryCompilerField.GetValue(query.Provider);
        var modelGenerator = (QueryModelGenerator)QueryModelGeneratorField.GetValue(queryCompiler);
        var queryModel = modelGenerator.ParseQuery(query.Expression);
        var database = (IDatabase)DataBaseField.GetValue(queryCompiler);
        var databaseDependencies = (DatabaseDependencies)DatabaseDependenciesField.GetValue(database);
        var queryCompilationContext = databaseDependencies.QueryCompilationContextFactory.Create(false);
        var modelVisitor = (RelationalQueryModelVisitor)queryCompilationContext.CreateQueryModelVisitor();
        modelVisitor.CreateQueryExecutor<TEntity>(queryModel);
        var sql = modelVisitor.Queries.First().ToString();

        return sql;
    }
}

この拡張メソッドをコードに追加した後は、このメソッドを次のように使用できます。

// Build a query using Entity Framework
var query = _context.Widgets.Where(w => w.IsReal && w.Id == 42);  
// Get the generated SQL
var sql = query.ToSql();  

紹介: http : //rion.io/2016/10/19/accessing-entity-framework-core-queries-behind-the-scenes-in-asp-net-core/およびhttps://gist.github.com / rionmonster / 2c59f449e67edf8cd6164e9fe66c545a

更新:EF Core 2.1がサポートされるように編集



Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ