• 查看ef core 3.1/3.0/2.1.2生成的sql语句


    • 对于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<TEntity>(this IQueryable<TEntity> query) where TEntity : class
    {
        var enumerator = query.Provider.Execute<IEnumerable<TEntity>>(query.Expression).GetEnumerator();
        var relationalCommandCache = enumerator.Private("_relationalCommandCache");
        var selectExpression = relationalCommandCache.Private<SelectExpression>("_selectExpression");
        var factory = relationalCommandCache.Private<IQuerySqlGeneratorFactory>("_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<T>(this object obj, string privateField) => (T)obj?.GetType().GetField(privateField, BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(obj);
    

      

    • 对于EFCore 3.0
    public static string ToSql<TEntity>(this IQueryable<TEntity> query)
            {
                var enumerator = query.Provider.Execute<IEnumerable<TEntity>>(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);
                }
            }
    

      

  • 相关阅读:
    C++进阶--placement new/delete
    mac_Mac item2常用快捷键
    linux_安装_安装编译phantomjs 2.0的方法_转
    linux_删除空文件(大小等于0的文件)的方法
    linux_根据关键词_路径下递归查找code
    linux_shell_获取日期相关
    php_中替换换行符
    linux_增加用户组_删除用户
    数据分析入门
    linux_vim_最佳快捷键
  • 原文地址:https://www.cnblogs.com/gskstudy/p/13306399.html
Copyright © 2020-2023  润新知