zoukankan      html  css  js  c++  java
  • 查看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);
                }
            }
    

      

  • 相关阅读:
    Maidsafe-去中心化互联网白皮书
    The Top 20 Cybersecurity Startups To Watch In 2021 Based On Crunchbase
    Top 10 Blockchain Security and Smart Contract Audit Companies
    The 20 Best Cybersecurity Startups To Watch In 2020
    Blockchain In Cybersecurity: 11 Startups To Watch In 2019
    004-STM32+BC26丨260Y基本控制篇(阿里云物联网平台)-在阿里云物联网平台上一型一密动态注册设备(Android)
    涂鸦开发-单片机+涂鸦模组开发+OTA
    000-ESP32学习开发-ESP32烧录板使用说明
    03-STM32+Air724UG远程升级篇OTA(阿里云物联网平台)-STM32+Air724UG使用阿里云物联网平台OTA远程更新STM32程序
    03-STM32+Air724UG远程升级篇OTA(自建物联网平台)-STM32+Air724UG实现利用http/https远程更新STM32程序(TCP指令,单片机程序检查更新)
  • 原文地址:https://www.cnblogs.com/gskstudy/p/13306399.html
Copyright © 2011-2022 走看看