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);
            }
        }
  • 相关阅读:
    left join 和 inner join 区别和优化
    认识位移操作符
    動態修改 XML 欄位
    (轉載)sql server xml字段的操作
    (轉)CSS 单行溢出文本显示省略号...的方法(兼容IE FF)
    (轉)Equal height boxes with CSS
    獲得瀏覽器顯示標簽的真實的長寬高
    轉:Jquery绑定img的click事件
    SqlLocalDB 的一些常用命令行
    转:css实现强制不换行/自动换行/强制换行
  • 原文地址:https://www.cnblogs.com/hjworld/p/13666961.html
Copyright © 2011-2022 走看看