2016-05-30 12 views
4

私はEntity Framework 7 Core RC2を使用しており、どのSQLコードが生成されているか確認する必要があります。 Entity Frameworkの以前のバージョンでは、私は次のように使用できます。EF7クエリからSQLコードを取得

クエリがたIQueryableオブジェクトです...しかしToTraceStringはEF7では利用できません
String sql = ((System.Data.Objects.ObjectQuery)query).ToTraceString(); 

EF7で同様のことを行うにはどうすればよいですか?

+2

可能な重複します(http: //stackoverflow.com/questions/26747837/how-to-log-queries-using-entity-framework-7) –

+0

これを試すことができます:http://rion.io/2016/10/19/accessing-entity- asp-net-core /にあるフレームワークのコア・クエリー・ビハインド・ザ・シーン。 – mikebridge

答えて

2

EF 7の名前がEntity Framework Coreに変更されたので、EF Coreのオプションをまとめます。

  • 組み込みまたはカスタムロギングの使用:

    IQueryable<>からSQL文をログに記録するための3つのアプローチがあります。 this tutorialで説明したように、選択したロガーまたは.NET Coreの組み込みLoggerを使用して実行中のクエリをログに記録します。

  • プロファイラを使用します。 MiniProfilerのような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(); 
    

    紹介を次のように

    public static class QueryableExtensions 
    { 
        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 PropertyInfo NodeTypeProviderField = QueryCompilerTypeInfo.DeclaredProperties.Single(x => x.Name == "NodeTypeProvider"); 
    
        private static readonly MethodInfo CreateQueryParserMethod = QueryCompilerTypeInfo.DeclaredMethods.First(x => x.Name == "CreateQueryParser"); 
    
        private static readonly FieldInfo DataBaseField = QueryCompilerTypeInfo.DeclaredFields.Single(x => x.Name == "_database"); 
    
        private static readonly FieldInfo QueryCompilationContextFactoryField = typeof(Database).GetTypeInfo().DeclaredFields.Single(x => x.Name == "_queryCompilationContextFactory"); 
    
        public static string ToSql<TEntity>(this IQueryable<TEntity> query) where TEntity : class 
        { 
         if (!(query is EntityQueryable<TEntity>) && !(query is InternalDbSet<TEntity>)) 
         { 
          throw new ArgumentException("Invalid query"); 
         } 
    
         var queryCompiler = (IQueryCompiler)QueryCompilerField.GetValue(query.Provider); 
         var nodeTypeProvider = (INodeTypeProvider)NodeTypeProviderField.GetValue(queryCompiler); 
         var parser = (IQueryParser)CreateQueryParserMethod.Invoke(queryCompiler, new object[] { nodeTypeProvider }); 
         var queryModel = parser.GetParsedQuery(query.Expression); 
         var database = DataBaseField.GetValue(queryCompiler); 
         var queryCompilationContextFactory = (IQueryCompilationContextFactory)QueryCompilationContextFactoryField.GetValue(database); 
         var queryCompilationContext = queryCompilationContextFactory.Create(false); 
         var modelVisitor = (RelationalQueryModelVisitor)queryCompilationContext.CreateQueryModelVisitor(); 
         modelVisitor.CreateQueryExecutor<TEntity>(queryModel); 
         var sql = modelVisitor.Queries.First().ToString(); 
    
         return sql; 
        } 
    } 
    

    あなたのコードに、この拡張メソッドを追加した後は、あなたがこの方法を使用することができます:ここで

は狂った反射コード(拡張メソッド)です。 http://rion.io/2016/10/19/accessing-entity-framework-core-queries-behind-the-scenes-in-asp-net-core/およびhttps://gist.github.com/rionmonster/2c59f449e67edf8cd6164e9fe66c545a

0

公共サービスとして:

var someQuery = (
    from projects in _context.projects 
    join issues in _context.issues on projects.Id equals issues.ProjectId into tmpMapp 
    from issues in tmpMapp.DefaultIfEmpty() 
    select issues 
) //.ToList() 
; 

// string sql = someQuery.ToString(); 
// string sql = Microsoft.EntityFrameworkCore.IQueryableExtensions.ToSql(someQuery); 
// string sql = Microsoft.EntityFrameworkCore.IQueryableExtensions1.ToSql(someQuery); 
// using Microsoft.EntityFrameworkCore; 
string sql = someQuery.ToSql(); 
System.Console.WriteLine(sql); 

そして、これらの拡張メソッド(.NETコア1.0、.NETのコア2.0 IQueryableExtensions用IQueryableExtensions1):[?Entity Frameworkの7を使用してクエリをログに記録する方法]の

using System; 
using System.Linq; 
using System.Reflection; 
using Microsoft.EntityFrameworkCore.Internal; 
using Microsoft.EntityFrameworkCore.Query; 
using Microsoft.EntityFrameworkCore.Query.Internal; 
using Microsoft.EntityFrameworkCore.Storage; 
using Remotion.Linq.Parsing.Structure; 


namespace Microsoft.EntityFrameworkCore 
{ 

    // https://stackoverflow.com/questions/1412863/how-do-i-view-the-sql-generated-by-the-entity-framework 
    // http://rion.io/2016/10/19/accessing-entity-framework-core-queries-behind-the-scenes-in-asp-net-core/ 

    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 PropertyInfo NodeTypeProviderField = 
      QueryCompilerTypeInfo.DeclaredProperties.Single(x => x.Name == "NodeTypeProvider"); 

     private static readonly MethodInfo CreateQueryParserMethod = 
      QueryCompilerTypeInfo.DeclaredMethods.First(x => x.Name == "CreateQueryParser"); 

     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 
     { 
      if (!(query is EntityQueryable<TEntity>) && !(query is InternalDbSet<TEntity>)) 
      { 
       throw new ArgumentException("Invalid query"); 
      } 

      var queryCompiler = (QueryCompiler) QueryCompilerField.GetValue(query.Provider); 
      var nodeTypeProvider = (INodeTypeProvider) NodeTypeProviderField.GetValue(queryCompiler); 
      var parser = (IQueryParser) CreateQueryParserMethod.Invoke(queryCompiler, new object[] {nodeTypeProvider}); 
      var queryModel = parser.GetParsedQuery(query.Expression); 
      var database = 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; 
     } 
    } 



    public class IQueryableExtensions1 
    { 
     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 PropertyInfo NodeTypeProviderField = 
      QueryCompilerTypeInfo.DeclaredProperties.Single(x => x.Name == "NodeTypeProvider"); 

     private static readonly MethodInfo CreateQueryParserMethod = 
      QueryCompilerTypeInfo.DeclaredMethods.First(x => x.Name == "CreateQueryParser"); 

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

     private static readonly FieldInfo QueryCompilationContextFactoryField = typeof(Database).GetTypeInfo() 
      .DeclaredFields.Single(x => x.Name == "_queryCompilationContextFactory"); 


     public static string ToSql<TEntity>(IQueryable<TEntity> query) where TEntity : class 
     { 
      if (!(query is EntityQueryable<TEntity>) && !(query is InternalDbSet<TEntity>)) 
      { 
       throw new ArgumentException("Invalid query"); 
      } 

      var queryCompiler = (IQueryCompiler) QueryCompilerField.GetValue(query.Provider); 

      var nodeTypeProvider = (INodeTypeProvider) NodeTypeProviderField.GetValue(queryCompiler); 
      var parser = 
       (IQueryParser) CreateQueryParserMethod.Invoke(queryCompiler, new object[] {nodeTypeProvider}); 
      var queryModel = parser.GetParsedQuery(query.Expression); 
      var database = DataBaseField.GetValue(queryCompiler); 
      var queryCompilationContextFactory = 
       (IQueryCompilationContextFactory) QueryCompilationContextFactoryField.GetValue(database); 
      var queryCompilationContext = queryCompilationContextFactory.Create(false); 
      var modelVisitor = (RelationalQueryModelVisitor) queryCompilationContext.CreateQueryModelVisitor(); 
      modelVisitor.CreateQueryExecutor<TEntity>(queryModel); 
      var sql = modelVisitor.Queries.First().ToString(); 

      return sql; 
     } 


    } 


} 
関連する問題