如何通过SqlConnection获取上次执行的SQL查询?

实际上,我的情景与此处提到的有点不同。 我问了其他问题。 但由于我没有在那里得到解决方案,我决定改变方法。

我的代码可以访问SqlConnection对象。 我无法访问所有其他ADO.NET对象,如SqlCommandSqlParameter等。 这些其他对象由Dapper Extensions ORM使用。

我的应用程序使用SqlConnection对象和Dapper Extensions方法执行SQL查询。 SQL查询由Dapper Extensions自动生成; 我无法访问生成的查询。 我想记录这个SQL查询。

我已经有了我的日志记录模块,我唯一需要的是连接对象执行的最后一个SQL查询。

如何通过SqlConnection获取上次执行的SQL查询?

以下操作无效,因为无法访问SqlCommand

如果我得到底层的SqlCommand ,我可以使用下面的代码从它构建查询; 不幸的是,我无法访问它。

 public string GetCommandLogString(IDbCommand command) { string outputText; if(command.Parameters.Count == 0) { outputText = command.CommandText; } else { StringBuilder output = new StringBuilder(); output.Append(command.CommandText); output.Append("; "); IDataParameter objIDataParameter; int parameterCount = command.Parameters.Count; for(int i = 0; i < parameterCount; i++) { objIDataParameter = (IDataParameter)command.Parameters[i]; output.Append(string.Format("{0} = '{1}'", objIDataParameter.ParameterName, objIDataParameter.Value)); if(i + 1 < parameterCount) { output.Append(", "); } } outputText = output.ToString(); } return outputText; } 

我过去使用的一种方法,当我不想依赖任何外部工具时(或缺少工具时,比如使用Access时)是使用数据库连接和命令“包装器”类,以便我可以将日志记录添加到他们的任何方法或属性中。

要使用它,您将要使用的任何连接传递给WrappedDbConnection的构造函数 –

 using (var conn = new WrappedDbConnection(GetMyConnection())) { // Do work using Dapper here against "conn" } 

(注意:当调用WrappedDbConnection实例的Dispose方法时,它将被传递到底层连接,因此您不需要为WrappedDbConnection使用“using”并为连接单独“使用” – 您只需要一个“使用” “,如上所示)。

您需要的两个类定义如下。

请注意,方法“ExecuteNonQuery”,“ExecuteReader”,“ExecuteReader”和“ExecuteScalar”中的Console.WriteLine调用将写出将要执行的查询。 您可能希望根据您的要求更改此选项,以便在查询完成写出查询或者您可能希望使用不同的输出,即Console.Writeline,但这些输出应该是足够简单的更改。

 public class WrappedDbConnection : IDbConnection { private readonly IDbConnection _conn; public WrappedDbConnection(IDbConnection connection) { if (connection == null) throw new ArgumentNullException(nameof(connection)); _conn = connection; } public string ConnectionString { get { return _conn.ConnectionString; } set { _conn.ConnectionString = value; } } public int ConnectionTimeout { get { return _conn.ConnectionTimeout; } } public string Database { get { return _conn.Database; } } public ConnectionState State { get { return _conn.State; } } public IDbTransaction BeginTransaction() { return _conn.BeginTransaction(); } public IDbTransaction BeginTransaction(IsolationLevel il) { return _conn.BeginTransaction(il); } public void ChangeDatabase(string databaseName) { _conn.ChangeDatabase(databaseName); } public void Close() { _conn.Close(); } public IDbCommand CreateCommand() { return new WrappedDbCommand(_conn.CreateCommand()); } public void Dispose() { _conn.Dispose(); } public void Open() { _conn.Open(); } } public class WrappedDbCommand : IDbCommand { private readonly IDbCommand _cmd; public WrappedDbCommand(IDbCommand command) { if (command == null) throw new ArgumentNullException(nameof(command)); _cmd = command; } public string CommandText { get { return _cmd.CommandText; } set { _cmd.CommandText = value; } } public int CommandTimeout { get { return _cmd.CommandTimeout; } set { _cmd.CommandTimeout = value; } } public CommandType CommandType { get { return _cmd.CommandType; } set { _cmd.CommandType = value; } } public IDbConnection Connection { get { return _cmd.Connection; } set { _cmd.Connection = value; } } public IDataParameterCollection Parameters { get { return _cmd.Parameters; } } public IDbTransaction Transaction { get { return _cmd.Transaction; } set { _cmd.Transaction = value; } } public UpdateRowSource UpdatedRowSource { get { return _cmd.UpdatedRowSource; } set { _cmd.UpdatedRowSource = value; } } public void Cancel() { _cmd.Cancel(); } public IDbDataParameter CreateParameter() { return _cmd.CreateParameter(); } public void Dispose() { _cmd.Dispose(); } public int ExecuteNonQuery() { Console.WriteLine($"[ExecuteNonQuery] {_cmd.CommandText}"); return _cmd.ExecuteNonQuery(); } public IDataReader ExecuteReader() { Console.WriteLine($"[ExecuteReader] {_cmd.CommandText}"); return _cmd.ExecuteReader(); } public IDataReader ExecuteReader(CommandBehavior behavior) { Console.WriteLine($"[ExecuteReader({behavior})] {_cmd.CommandText}"); return _cmd.ExecuteReader(); } public object ExecuteScalar() { Console.WriteLine($"[ExecuteScalar] {_cmd.CommandText}"); return _cmd.ExecuteScalar(); } public void Prepare() { _cmd.Prepare(); } }