[英]How to log/get a SQL query auto-generated by Dapper Extensions?
I am using Dapper Extensions (DE) as ORM.我使用 Dapper Extensions (DE) 作为 ORM。 It is consumed in Data Access Layer which is implemented using Repository pattern.
它在使用存储库模式实现的数据访问层中使用。 SQL Express is back-end RDBMS.
SQL Express 是后端 RDBMS。
DE automatically generates most of the queries for me. DE 会自动为我生成大部分查询。 I want to log those auto-generated queries for debugging purpose.
我想记录那些自动生成的查询以进行调试。
There are two ways I can see to achieve this: -我可以看到有两种方法可以实现这一目标:-
How to log/get a SQL query auto-generated by Dapper Extensions without using any other logging tool?如何在不使用任何其他日志记录工具的情况下记录/获取由 Dapper Extensions 自动生成的 SQL 查询?
The other similar question is about Dapper. 另一个类似的问题是关于 Dapper。 This question is about Dapper Extensions.
这个问题是关于 Dapper 扩展的。
Dapper Extensions project is open source; Dapper Extensions 项目是开源的; everyone knows that.
每个人都知道。 I downloaded it from GitHub and modified it to meet my needs.
我是从 GitHub 上下载下来的,并根据自己的需要进行了修改。
Dapper Extensions build/generate SQL query internally in SqlGeneratorImpl
class. Dapper 扩展在
SqlGeneratorImpl
类中内部构建/生成 SQL 查询。 There are multiple methods in this class those generate the various queries.此类中有多种方法可以生成各种查询。
I added following property in DapperExtensions.DapperExtensions
static
class:我在
DapperExtensions.DapperExtensions
static
类中添加了以下属性:
static string lastGeneratedQuery;
public static string LastGeneratedQuery
{
get
{
lock(_lock)
{
return lastGeneratedQuery;
}
}
internal set
{
lock(_lock)
{
lastGeneratedQuery = value;
}
}
}
Also, set this property in various methods of SqlGeneratorImpl
class.此外,在
SqlGeneratorImpl
类的各种方法中设置此属性。 Following is an example how I set it in Select
method.以下是我如何在
Select
方法中设置它的示例。
public virtual string Select(IClassMapper classMap, IPredicate predicate, IList<ISort> sort, IDictionary<string, object> parameters)
{
......
......
StringBuilder sql = new StringBuilder(string.Format("SELECT {0} FROM {1}",
......
......
DapperExtensions.LastGeneratedQuery = sql.ToString();
return sql.ToString();
}
Basic tests run well;基本测试运行良好; I have not yet tested this thoroughly.
我还没有彻底测试过。 I will update this answer in case of any change.
如有任何更改,我将更新此答案。
Please note that I do not recommend this as standard solution;
请注意,我不建议将此作为标准解决方案;
this is just a hack that works for my needs.
这只是一个适合我需要的黑客。
I would really like to see this as a regular feature in library.
我真的很想将其视为图书馆的常规功能。
Please post an answer if you have better solution.
如果您有更好的解决方案,请发布答案。
Otherwise,
please comment to improve the solution suggested here.
否则,
请发表评论以改进此处建议
的解决方案。
After merging this pull request in master
branch, hopefully this is now available out of the box and no need to download and modify the toolkit source code anymore.在
master
分支中合并此拉取请求后,希望现在可以开箱即用,不再需要下载和修改工具包源代码。 Note that I have not verified this.请注意,我尚未对此进行验证。
Looking at the comment from @MarcGravell and this question about doing the same with Dapper, MiniProfiler.Integrations
is better way to implement logging for Dapper Extensions.纵观评论从@MarcGravell和该做同样与小巧玲珑的问题,
MiniProfiler.Integrations
是落实日志记录小巧玲珑的扩展更好的办法。
Above linked question is about Dapper.上面链接的问题是关于 Dapper。 But Dapper Extensions uses Dapper internally.
但是 Dapper Extensions 在内部使用 Dapper。 So, if logging is implemented for Dapper, same works for Dapper Extensions as well.
因此,如果为 Dapper 实现了日志记录,那么同样适用于 Dapper 扩展。
More details could be found on GitHub .更多细节可以在GitHub上找到。
Sample code is as below:示例代码如下:
var factory = new SqlServerDbConnectionFactory(connectionString);
CustomDbProfiler cp = new CustomDbProfiler();
using(var connection = DbConnectionFactoryHelper.New(factory, cp))
{
//DB Code
}
string log = cp.ProfilerContext.GetCommands();
You can use in-build CustomDbProfiler
using CustomDbProfiler.Current
if that suits your need.如果满足您的需要,您可以使用
CustomDbProfiler
使用CustomDbProfiler.Current
。 cp.ProfilerContext.GetCommands()
will return ALL the commands (success and failed) no matter how many times you call the method.无论您调用该方法多少次,
cp.ProfilerContext.GetCommands()
都将返回所有命令(成功和失败)。 I am not sure but, it might be maintaining concatenated string ( StringBuilder
may be) internally.我不确定但是,它可能在内部维护连接的字符串(
StringBuilder
可能是)。 If this is the case, this may slow down the performance.如果是这种情况,这可能会降低性能。 But, in my case, logging is disabled by default.
但是,就我而言,默认情况下禁用日志记录。 I only enable logging when I need to debug something.
我只在需要调试时启用日志记录。 So this is not a problem for me.
所以这对我来说不是问题。
This also may raise memory footprint issue if single connection is used over very large scope.如果在非常大的范围内使用单个连接,这也可能会引发内存占用问题。 To avoid this, make sure
CustomDbProfiler
instance is disposed properly.为避免这种情况,请确保正确处理
CustomDbProfiler
实例。
As mentioned in question, initially, I wanted to avoid this way (using external tool/library) .如前所述,最初,我想避免这种方式(使用外部工具/库) 。 But,
MiniProfiler.Integrations
is NOT writing the log itself.但是,
MiniProfiler.Integrations
不会写入日志本身。 I can simply get all the queries generated and provide those to my logger module to dump into the file.我可以简单地生成所有查询并将它们提供给我的记录器模块以转储到文件中。 That is why, this looks more suitable to me now.
这就是为什么,这现在看起来更适合我。
MiniProfiler.dll internally implements similar logic (in StackExchange.Profiling.Data.ProfiledDbConnection
and StackExchange.Profiling.Data.ProfiledDbCommand
classes) which is mentioned here and here . MiniProfiler.dll 在内部实现了类似的逻辑(在
StackExchange.Profiling.Data.ProfiledDbConnection
和StackExchange.Profiling.Data.ProfiledDbCommand
类中),这里和这里提到。 So, if I decide to (in future may be) bypass MiniProfiler, I can use this implementation myself.所以,如果我决定(将来可能会)绕过 MiniProfiler,我可以自己使用这个实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.