Sql拦截器

拦截器

Chloe 借鉴 EF,支持了拦截器功能。通过该功能可以拦截 sql 语句和监视 sql 执行用时。
拦截器定义:
自定义的拦截器必须实现 IDbCommandInterceptor 接口。

class DbCommandInterceptor : IDbCommandInterceptor
{
    /* 执行 DbCommand.ExecuteReader() 时调用 */
    public void ReaderExecuting(IDbCommand command, DbCommandInterceptionContext<IDataReader> interceptionContext)
    {
        interceptionContext.DataBag.Add("startTime", DateTime.Now);
        Console.WriteLine(command.CommandText);
    }
    /* 执行 DbCommand.ExecuteReader() 后调用 */
    public void ReaderExecuted(IDbCommand command, DbCommandInterceptionContext<IDataReader> interceptionContext)
    {
        DateTime startTime = (DateTime)(interceptionContext.DataBag["startTime"]);
        Console.WriteLine(DateTime.Now.Subtract(startTime).TotalMilliseconds);
        if (interceptionContext.Exception == null)
            Console.WriteLine(interceptionContext.Result.FieldCount);
    }

    /* 执行 DbCommand.ExecuteNonQuery() 时调用 */
    public void NonQueryExecuting(IDbCommand command, DbCommandInterceptionContext<int> interceptionContext)
    {
        interceptionContext.DataBag.Add("startTime", DateTime.Now);
        Console.WriteLine(command.CommandText);
    }
    /* 执行 DbCommand.ExecuteNonQuery() 后调用 */
    public void NonQueryExecuted(IDbCommand command, DbCommandInterceptionContext<int> interceptionContext)
    {
        DateTime startTime = (DateTime)(interceptionContext.DataBag["startTime"]);
        Console.WriteLine(DateTime.Now.Subtract(startTime).TotalMilliseconds);
        if (interceptionContext.Exception == null)
            Console.WriteLine(interceptionContext.Result);
    }

    /* 执行 DbCommand.ExecuteScalar() 时调用 */
    public void ScalarExecuting(IDbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
        interceptionContext.DataBag.Add("startTime", DateTime.Now);
        Console.WriteLine(command.CommandText);
    }
    /* 执行 DbCommand.ExecuteScalar() 后调用 */
    public void ScalarExecuted(IDbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
        DateTime startTime = (DateTime)(interceptionContext.DataBag["startTime"]);
        Console.WriteLine(DateTime.Now.Subtract(startTime).TotalMilliseconds);
        if (interceptionContext.Exception == null)
            Console.WriteLine(interceptionContext.Result);
    }
}

全局拦截器:
这种用法针对所有的 DbContext 有效,建议在程序启动时添加。

IDbCommandInterceptor interceptor = new DbCommandInterceptor();
DbInterception.Add(interceptor);

单个DbContext拦截器:
这种用法只会对单个 DbContext 有效,建议在创建 DbContext 时添加。

IDbContext context = new MsSqlContext("Your connection string");
IDbCommandInterceptor interceptor = new DbCommandInterceptor();
context.Session.AddInterceptor(interceptor);