zoukankan      html  css  js  c++  java
  • 查看EF CORE 3.1/3.0/2.1.2生成的SQL语句

    转载自https://www.cnblogs.com/gskstudy/p/13306399.html

    对于EFCore 3.1

    using System.Linq;
    using System.Reflection;
    using System.Collections.Generic;
    using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
    using Microsoft.EntityFrameworkCore.Query;

    public static string ToSql(this IQueryable query) where TEntity : class
    {
    var enumerator = query.Provider.Execute<IEnumerable>(query.Expression).GetEnumerator();
    var relationalCommandCache = enumerator.Private("_relationalCommandCache");
    var selectExpression = relationalCommandCache.Private("_selectExpression");
    var factory = relationalCommandCache.Private("_querySqlGeneratorFactory");

    var sqlGenerator = factory.Create();
    var command = sqlGenerator.GetCommand(selectExpression);
    
    string sql = command.CommandText;
    return sql;
    

    }

    private static object Private(this object obj, string privateField) => obj?.GetType().GetField(privateField, BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(obj);
    private static T Private(this object obj, string privateField) => (T)obj?.GetType().GetField(privateField, BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(obj);
      

    对于EFCore 3.0

    public static string ToSql(this IQueryable query)
    {
    var enumerator = query.Provider.Execute<IEnumerable>(query.Expression).GetEnumerator();
    var enumeratorType = enumerator.GetType();
    var selectFieldInfo = enumeratorType.GetField("_selectExpression", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException($"cannot find field _selectExpression on type {enumeratorType.Name}");
    var sqlGeneratorFieldInfo = enumeratorType.GetField("_querySqlGeneratorFactory", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException($"cannot find field _querySqlGeneratorFactory on type {enumeratorType.Name}");
    var selectExpression = selectFieldInfo.GetValue(enumerator) as SelectExpression ?? throw new InvalidOperationException($"could not get SelectExpression");
    var factory = sqlGeneratorFieldInfo.GetValue(enumerator) as IQuerySqlGeneratorFactory ?? throw new InvalidOperationException($"could not get IQuerySqlGeneratorFactory");
    var sqlGenerator = factory.Create();
    var command = sqlGenerator.GetCommand(selectExpression);
    var sql = command.CommandText;
    return sql;
    }
      

    对于EFCore 2.1.2

    static class IQueryableToSql
    {
    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 queryContextFactoryField = QueryCompilerTypeInfo.DeclaredFields.First(x => x.Name == "_queryContextFactory");
    private static readonly FieldInfo loggerField = QueryCompilerTypeInfo.DeclaredFields.First(x => x.Name == "_logger");
    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 sql, IReadOnlyDictionary<string, object> parameters) ToSql<TEntity>(IQueryable<TEntity> query) where TEntity : class
            {
                var queryCompiler = (QueryCompiler)QueryCompilerField.GetValue(query.Provider);
                var queryContextFactory = (IQueryContextFactory)queryContextFactoryField.GetValue(queryCompiler);
                var logger = (Microsoft.EntityFrameworkCore.Diagnostics.IDiagnosticsLogger<DbLoggerCategory.Query>)loggerField.GetValue(queryCompiler);
                var queryContext = queryContextFactory.Create();
                var modelGenerator = (QueryModelGenerator)QueryModelGeneratorField.GetValue(queryCompiler);
                var newQueryExpression = modelGenerator.ExtractParameters(logger, query.Expression, queryContext);
                var queryModel = modelGenerator.ParseQuery(newQueryExpression);
                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 command = modelVisitor.Queries.First().CreateDefaultQuerySqlGenerator()
                    .GenerateSql(queryContext.ParameterValues);
    
                return (command.CommandText, queryContext.ParameterValues);
            }
        }
  • 相关阅读:
    PHP基础学习笔记(一)
    安装wampserver之后,浏览器中输入localhost页面显示IIS7解决办法
    HTML5常识总结(一)
    AngularJs中的服务
    AngularJs中的directives(指令part1)
    Happy Number——LeetCode
    Binary Tree Zigzag Level Order Traversal——LeetCode
    Construct Binary Tree from Preorder and Inorder Traversal——LeetCode
    Construct Binary Tree from Inorder and Postorder Traversal——LeetCode
    Convert Sorted Array to Binary Search Tree——LeetCode
  • 原文地址:https://www.cnblogs.com/hjworld/p/13666961.html
Copyright © 2011-2022 走看看