ef core 获取SQL语句

2020-11-13 09:06发布

问题描述

网上最多就是类似于在 IQueryable 上面扩展方法,这样只能获取查询列表的SQL 语句,但如果 我是查

_dbContext.Set<T>().AsNoTracking().FirstOrDefaultAsync(predicate);

这样,我只能使用

_dbContext.Set<T>().AsNoTracking().ToQueryString();

来获取SQL语句,这个 ToQueryString 方法并没有 sql语句的 where 部分语句,也就是没有条件。只生成了 select 字段列表 from 表。

我想要的

我想的是能不能获取到的 SQL 语句 ,跟在 Sql Server Profiler 一样。 或者像 SqlSugar一样支持 Ado 切面。但现在 EF core 好像是没有办法的。

sql sugar获取 SQL 语句
            var db = new SqlSugarClient(new ConnectionConfig()
            {
                ConnectionString = ConnStr,
                DbType = DbType.SqlServer,
                IsAutoCloseConnection = true,
                InitKeyType = InitKeyType.Attribute
            });
            //sql执行前
            db.Aop.OnLogExecuting = (sql, pars) =>
            {
                Debug.WriteLine("SQL执行前==>>>" + sql + "\r\n" + db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value)));
                if (db.TempItems == null) db.TempItems = new Dictionary<string, object>();
            };
            //sql执行后
            db.Aop.OnLogExecuted = (sql, pars) =>
            {
                Debug.WriteLine("SQL执行后==>>>" + sql + "\r\n" + db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value)));
            };
            //sql执行错误
            db.Aop.OnError = (pars) =>
            {

            };

标签:
3条回答
做个烂人
2楼-- · 2020-11-13 09:43

貌似不需要,可以直接打印在console里面

查看更多
不美不萌又怎样
3楼-- · 2020-11-13 09:57

我在以前ef2.0的时候通过下面的代码对 IQueryable<TEntity>扩展是可以的。
尝试一下以下代码:

    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 FieldInfo QueryModelGeneratorField = QueryCompilerTypeInfo.DeclaredFields.First(x => x.Name == "_queryModelGenerator");

        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
        {
            var queryCompiler = (QueryCompiler)QueryCompilerField.GetValue(query.Provider);
            var modelGenerator = (QueryModelGenerator)QueryModelGeneratorField.GetValue(queryCompiler);
            var queryModel = modelGenerator.ParseQuery(query.Expression);
            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 sql = modelVisitor.Queries.First().ToString();

            return sql;
        }
    }
查看更多
虎瘦雄心在
4楼-- · 2020-11-13 10:01

有很多中方法实现
1、自定义DbCommandInterceptor
2、自定义Logger,在输出日志中拦截处理

查看更多
登录 后发表回答