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

Mla*_*vic 35 dapper

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

haz*_*ack 24

我遇到了同样的问题,并在进行了一些搜索之后实现了一些代码但没有现成的东西.有上的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
}
Run Code Online (Sandbox Code Playgroud)

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

File.WriteAllText("SqlScripts.txt", CustomDbProfiler.Current.ProfilerContext.BuildCommands());
Run Code Online (Sandbox Code Playgroud)

  • 像MySql的梦一样工作..在10分钟内找出我的问题.更改为CustomDbProfiler.Current.ProfilerContext.GetCommands().谢谢! (4认同)
  • 这个答案对Net Core有效吗?我缺少`CustomDbProfiler.Current.ProfilerContext`。 (3认同)

Mar*_*ell 11

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

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

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

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

  • 嗨马克,你能举一个你担心的那种攻击的例子吗? (4认同)

Mar*_*son 9

您应该考虑使用位于SQL Management Studio \xe2\x86\x92 Extras \xe2\x86\x92 SQL Server Profiler菜单中的 SQL 探查器(不需要 Dapper 扩展 - 当其他 RDBMS 也有 SQL 探查器工具时,可以与其他 RDBMS 一起使用) 。

\n

然后,开始新的会话。

\n

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

\n
exec sp_executesql N'SELECT * FROM Updates WHERE CAST(Product_ID as VARCHAR(50)) = @appId AND (Blocked IS NULL OR Blocked = 0) \n                    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'\n
Run Code Online (Sandbox Code Playgroud)\n


Mar*_*ese 8

尝试Dapper.Logging

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

在我看来,唯一的缺点是文档很少,但我认为这只是因为它是一个新项目(截至撰写本文时)。我必须深入研究一下该存储库才能理解它并根据我的喜好对其进行配置,但现在它工作得很好。

从文档中:

该工具由DbConnection和 的 简单装饰器组成DbCommand,它们跟踪执行时间并将消息写入 ILogger<T>. 可以ILogger<T>由任何日​​志框架(例如 Serilog)处理。结果类似于默认的 EF Core 日志记录行为。

IDbConnectionFactory该库声明了一个辅助方法,用于在 IoC 容器中注册 。连接工厂与 SQL 提供程序无关。这就是为什么你必须指定真正的工厂方法:

services.AddDbConnectionFactory(prv => new SqlConnection(conStr));
Run Code Online (Sandbox Code Playgroud)

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

private readonly IDbConnectionFactory _connectionFactory;
public GetProductsHandler(IDbConnectionFactory connectionFactory)
{
    _connectionFactory = connectionFactory;
}
Run Code Online (Sandbox Code Playgroud)

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

using (DbConnection db = _connectionFactory.CreateConnection())
{
    //...
}
Run Code Online (Sandbox Code Playgroud)


MrE*_*ndo 6

这并不详尽,本质上是一些 hack,但如果您有 SQL 并且想要初始化参数,那么它对于基本调试很有用。设置此扩展方法,然后根据需要在任何地方调用它。

public static class DapperExtensions
{
    public static string ArgsAsSql(this DynamicParameters args)
    {
        if (args is null) throw new ArgumentNullException(nameof(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();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以在立即窗口或监视窗口中使用它来获取 SQL。