C# Dapper-获取有关已执行查询语句的信息
我用Dapper替换了MySQL.Data包。要从数据库中获取一个用户,我现在要做的就是C# Dapper-获取有关已执行查询语句的信息,c#,dapper,C#,Dapper,我用Dapper替换了MySQL.Data包。要从数据库中获取一个用户,我现在要做的就是 public Task<User> GetUser(string username) { using IDbConnection databaseConnection = new MySqlConnection("connectionString"); DynamicParameters parameters = new DynamicPa
public Task<User> GetUser(string username)
{
using IDbConnection databaseConnection = new MySqlConnection("connectionString");
DynamicParameters parameters = new DynamicParameters();
parameters.Add("@username", username, DbType.String);
return databaseConnection.QueryFirstOrDefaultAsync<User>(
"SELECT * FROM person WHERE username = @username",
parameters);
}
public任务GetUser(字符串用户名)
{
使用IDbConnection databaseConnection=new MySqlConnection(“connectionString”);
DynamicParameters参数=新的DynamicParameters();
添加(“@username”,username,DbType.String);
return databaseConnection.QueryFirstOrDefaultAsync(
“从用户名=@username的人员中选择*”,
参数);
}
但是我想添加一些跟踪级别的日志记录。有没有办法在执行查询字符串之前提取它?创建您自己的IDbCommand,它将封装您真正的IDbCommand并记录您想要截取的内容。 但是,由于Dapper自动创建IDbConnection,您还必须创建自己的IDbConnection(请参见下面的
CreateCommand
),它将包装您真正的IDbConnection,以防使用您自己的IDbConnection
例如:
/// <summary>
/// This is just a wrapper around IDbConnection,
/// which allows us to build a wrapped IDbCommand for logging/debugging
/// </summary>
public class InterceptedDbConnection : IDbConnection
{
private readonly IDbConnection _conn;
public InterceptedDbConnection(IDbConnection connection)
{
_conn = connection;
}
public string ConnectionString { get => _conn.ConnectionString; set => _conn.ConnectionString = value; }
public int ConnectionTimeout => _conn.ConnectionTimeout;
public string Database => _conn.Database;
public ConnectionState State => _conn.State;
public IDbTransaction BeginTransaction() => _conn.BeginTransaction();
public IDbTransaction BeginTransaction(IsolationLevel il) => _conn.BeginTransaction(il);
public void ChangeDatabase(string databaseName) => _conn.ChangeDatabase(databaseName);
public void Close() => _conn.Close();
public IDbCommand CreateCommand()
{
// Wrap real command under InterceptedDbCommand
IDbCommand underlyingCommand = _conn.CreateCommand();
return new InterceptedDbCommand(underlyingCommand);
// you could also save this into a "LastCommand" to expose it
// and explore parameter types that Dapper used
}
public void Dispose() => _conn.Dispose();
public void Open() => _conn.Open();
}
/// <summary>
/// This is just a wrapper around IDbCommand,
/// which allows us to log queries
/// or inspect how Dapper is passing our Parameters
/// </summary>
public class InterceptedDbCommand : IDbCommand
{
private readonly IDbCommand _cmd;
public InterceptedDbCommand(IDbCommand command)
{
_cmd = command;
}
public string CommandText { get => _cmd.CommandText; set => _cmd.CommandText = value; }
public int CommandTimeout { get => _cmd.CommandTimeout; set => _cmd.CommandTimeout = value; }
public CommandType CommandType { get => _cmd.CommandType; set => _cmd.CommandType = value; }
public IDbConnection Connection { get => _cmd.Connection; set => _cmd.Connection = value; }
public IDataParameterCollection Parameters => _cmd.Parameters;
public IDbTransaction Transaction { get => _cmd.Transaction; set => _cmd.Transaction = value; }
public UpdateRowSource UpdatedRowSource { get => _cmd.UpdatedRowSource; set => _cmd.UpdatedRowSource = value; }
public void Cancel() => _cmd.Cancel();
public IDbDataParameter CreateParameter() => _cmd.CreateParameter();
public void Dispose() => _cmd.Dispose();
public void Prepare() => _cmd.Prepare();
public int ExecuteNonQuery()
{
// TODO: Log _cmd.CommandText + _cmd.Parameters
return _cmd.ExecuteNonQuery();
}
public IDataReader ExecuteReader()
{
// TODO: Log _cmd.CommandText + _cmd.Parameters
return _cmd.ExecuteReader();
}
public IDataReader ExecuteReader(CommandBehavior behavior)
{
// TODO: Log _cmd.CommandText + _cmd.Parameters
return _cmd.ExecuteReader(behavior);
}
public object ExecuteScalar()
{
// TODO: Log _cmd.CommandText + _cmd.Parameters
return _cmd.ExecuteScalar();
}
}
如前所述,MiniProfiler可能会有所帮助。这个问题是关于简洁的扩展;但是同样的事情也适用于Dapper。或者,您也可以使用wrapper over
DbConnection
,正如前面所解释的那样。@AmitJoshi非常感谢您,但我不想为此使用外部工具,它只是关于访问生成的sql命令:)并感谢您的第二次评论,但我觉得这真的不对。我必须重新实现/包装整个东西,以便访问它。。。必须有一个更好的解决方案来解决这个问题,Dapper不公开这个功能,因为Dapper的目的是尽可能简单和轻量级。
IDbConnection databaseConnection = new InterceptedDbConnection(MySqlConnection("connectionString"));