從EF Core查詢中獲取SQL代碼

entity-framework-core

我正在使用Entity Framework 7 Core RC2 (重命名為:EF Core),我需要查看正在生成的SQL代碼。在先前版本的Entity Framework中,我可以使用以下內容:

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

其中query是IQueryable對象...但是EF Core中沒有ToTraceString。

我怎樣才能在EF Core中做類似的事情?

熱門答案

由於EF 7重命名為Entity Framework Core,因此我將總結EF Core的選項。

IQueryable<>記錄SQL語句有3種方法:

  • 使用內置或自定義日誌記錄 。使用您選擇的記錄器或本教程中提到的.NET Core中的內置Logger記錄執行查詢。
  • 使用Profiler 。使用像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合法嗎? 是的,了解原因