有没有办法使用Dapper跟踪\ log sql?

时间:2013-08-30 09:50:18

标签: dapper

有没有办法将生成的sql转储到Debug日志或其他什么?我在winforms解决方案中使用它,因此迷你探测器的想法对我不起作用。

6 个答案:

答案 0 :(得分:23)

我遇到了同样的问题并在进行了一些搜索后实现了一些代码,但没有现成的东西。 nuget MiniProfiler.Integrations上有一个包我想分享。

更新V2 :它支持与其他数据库服务器一起使用,对于MySQL需要MiniProfiler.Integrations.MySql

以下是使用SQL Server的步骤:

1.实现连接

var factory = new SqlServerDbConnectionFactory(_connectionString);
using (var connection = DbConnectionFactoryHelper.New(factory, CustomDbProfiler.Current))
{
 // your code
}

2.完成所有工作后,如果需要,将所有命令写入文件

File.WriteAllText("SqlScripts.txt", CustomDbProfiler.Current.ProfilerContext.BuildCommands());

答案 1 :(得分:9)

Dapper目前没有仪器点。正如您所指出的,这可能是由于我们(作为作者)使用迷你探查器来处理这个问题。但是,如果它有帮助,mini-profiler的核心部分实际上是设计为架构中立的,我知道其他人使用它与winforms,wpf,wcf等 - 这将使您可以访问分析/跟踪连接包装

理论上,完全可以添加一些毯子捕获点,但我关注两件事:

  • (主要)安全性:因为dapper没有上下文的概念,所以真的很容易让恶意代码安静地附着来嗅探通过dapper发送的所有sql流量;我真的不喜欢这种声音(这不是“装饰器”方法的问题,因为调用者拥有连接,因此记录上下文)
  • (次要)表现:但......实际上,很难说简单的委托检查(在大多数情况下可能是null)会产生很大的影响

当然,您可以做的另一件事是:从mini-profiler中窃取连接包装器代码,并用以下内容替换profiler-context内容:Debug.WriteLine等。

答案 2 :(得分:2)

这不是详尽无遗的,本质上是一些黑客攻击,但是如果你有你的sql并且想要初始化你的参数,它对于基本调试很有用。

public static class DapperExtensions
    {
        public static string ArgsAsSql(this DynamicParameters args)
        {
            var sb = new StringBuilder();
            foreach (var name in args.ParameterNames)
            {
                var pValue = args.Get<dynamic>(name);

                var type = pValue.GetType();

                if (type == typeof(DateTime))
                    sb.AppendFormat("DECLARE @{0} DATETIME ='{1}'\n", name, pValue.ToString("yyyy-MM-dd HH:mm:ss.fff"));
                else if (type == typeof(bool))
                    sb.AppendFormat("DECLARE @{0} BIT = {1}\n", name, (bool)pValue ? 1 : 0);
                else if (type == typeof(int))
                    sb.AppendFormat("DECLARE @{0} INT = {1}\n", name, pValue);
                else if (type == typeof(List<int>))
                    sb.AppendFormat("-- REPLACE @{0} IN SQL: ({1})\n", name, string.Join(",", (List<int>)pValue));
                else
                    sb.AppendFormat("DECLARE @{0} NVARCHAR(MAX) = '{1}'\n", name, pValue.ToString());
            }

            return sb.ToString();
        }
    }

然后您可以在立即使用它或观看窗口来获取SQL。

答案 3 :(得分:2)

只是在这里添加一个更新,因为我看到这个问题仍然有很多点击 - 这些天我使用GlimpseStackify Prefix,它们都具有sql命令跟踪功能。

当我问原问题但解决同样的问题时,这并不是我想要的。

答案 4 :(得分:2)

您应该考虑使用位于 SQL Management Studio →其他→SQL Server Profiler 菜单中的SQL事件探查器(不需要Dapper扩展-当其他RDBMS也具有SQL事件探查器工具时,它们也可以使用。

然后,开始新的会话。

例如,您将获得类似的内容(您将看到所有参数和完整的SQL字符串):

exec sp_executesql N'SELECT * FROM Updates WHERE CAST(Product_ID as VARCHAR(50)) = @appId AND (Blocked IS NULL OR Blocked = 0) 
                    AND (Beta IS NULL OR Beta = 0 OR @includeBeta = 1) AND (LangCode IS NULL OR LangCode IN (SELECT * FROM STRING_SPLIT(@langCode, '','')))',N'@appId nvarchar(4000),@includeBeta bit,@langCode nvarchar(4000)',@appId=N'fea5b0a7-1da6-4394-b8c8-05e7cb979161',@includeBeta=0,@langCode=N'de'

答案 5 :(得分:2)

尝试Dapper.Logging

您可以从NuGet获取它。它的工作方式是将创建实际数据库连接的代码传递给创建包装的连接的工厂。每当打开或关闭包装的连接或对它运行查询时,都会记录该连接。您可以配置日志消息模板和其他设置,例如是否保存SQL参数。经过的时间也会保存。

在我看来,唯一的缺点是文档稀疏,但是我认为这仅仅是因为它是一个新项目(在撰写本文时)。我不得不仔细研究该回购协议,以了解它并按照自己的喜好对其进行配置,但现在它的运行效果很好。

从文档中:

该工具由DbConnectionDbCommand跟踪执行时间并将消息写入 ILogger<T>ILogger<T>可以由任何日​​志记录框架处理 (例如Serilog)。结果类似于默认的EF Core日志记录 行为。

lib声明用于注册 IDbConnectionFactory在IoC容器中。连接工厂是 SQL Provider不可知。这就是为什么您必须指定真实工厂 方法:

services.AddDbConnectionFactory(prv => new SqlConnection(conStr));

注册后,可以将IDbConnectionFactory注入 需要SQL连接的类。

private readonly IDbConnectionFactory _connectionFactory;
public GetProductsHandler(IDbConnectionFactory connectionFactory)
{
    _connectionFactory = connectionFactory;
}

IDbConnectionFactory.CreateConnection将返回修饰符 记录活动的版本。

using (DbConnection db = _connectionFactory.CreateConnection())
{
    //...
}