Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Dapper-获取有关已执行查询语句的信息_C#_Dapper - Fatal编程技术网

C# Dapper-获取有关已执行查询语句的信息

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

我用Dapper替换了MySQL.Data包。要从数据库中获取一个用户,我现在要做的就是

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"));