如何定义要查询数据库的查询数量?

时间:2018-11-08 09:56:14

标签: asp.net .net asp.net-mvc logging nhibernate

我有一个带有控制器的旧版asp.net mvc项目,该控制器返回视图和一些Web api控制器。该数据库是ms sql。 ORM是NHibernate。 我想记录有多少查询进入数据库以执行某项操作。 像这样的东西

{namepage}, {controller}, {action} - {count of queries}

我认为可以通过全局过滤器来实现。 你能给我关于我该怎么做的想法吗?

2 个答案:

答案 0 :(得分:0)

SessionFactory提供的统计数据是option的一种可能。这里的问题可能是SessionFactory通常在该过程的整个生命周期内都有效,因此我不确定如何仅将该操作的统计信息隔离出来。

您还可以探索interceptors的概念。 IIRC,有一种方法可以与查询准备/执行相关。

答案 1 :(得分:0)

我认为您将无法通过动作过滤器执行此操作。过滤器并不真正知道controller方法内部发生了什么。

除了大卫所说的以外,我认为拦截器可能是解决之道。拦截器here

有一个很好的实现

这是实现的副本,因为人们对链接感到生气

using System;       
using NHibernate;
using NHibernate.Type;

public class AuditInterceptor : EmptyInterceptor {

    private int updates;
    private int creates;
    private int loads;

    public override void OnDelete(object entity,
                                  object id,
                                  object[] state,
                                  string[] propertyNames,
                                  IType[] types)
    {
        // do nothing
    }

    public override bool OnFlushDirty(object entity, 
                                      object id, 
                                      object[] currentState,
                                      object[] previousState,
                                      string[] propertyNames,
                                      IType[] types)
    {
        if ( entity is IAuditable ) {
            updates++;
            for ( int i=0; i < propertyNames.Length; i++ ) {
                if ( "lastUpdateTimestamp".Equals( propertyNames[i] ) ) {
                    currentState[i] = new DateTime();
                    return true;
                }
            }
        }
        return false;
    }

    public override bool OnLoad(object entity, 
                                object id, 
                                object[] state,
                                string[] propertyNames,
                                IType[] types)
    {
        if ( entity is IAuditable ) {
            loads++;
        }
        return false;
    }

    public override bool OnSave(object entity, 
                                object id, 
                                object[] state,
                                string[] propertyNames,
                                IType[] types)
    {
        if ( entity is IAuditable ) {
            creates++;
            for ( int i=0; i<propertyNames.Length; i++ ) {
                if ( "createTimestamp".Equals( propertyNames[i] ) ) {
                    state[i] = new DateTime();
                    return true;
                }
            }
        }
        return false;
    }

    public override void AfterTransactionCompletion(ITransaction tx)
    {
        if ( tx.WasCommitted ) {
            System.Console.WriteLine(
                "Creations: " + creates +
                ", Updates: " + updates +
                ", Loads: " + loads);
        }
        updates=0;
        creates=0;
        loads=0;
    }

}

您可以用读取StackTrace的内容替换方法主体,但可以使用

进行Controller调用
var stackTrace = new StackTrace();
            var method =
                stackTrace.GetFrames()
                    .Select(f => f.GetMethod())
                    .Where(
                        m =>
                            m.IsPublic && m.DeclaringType != null &&
                            m.DeclaringType.IsSubclassOf(typeof(Controller)))
                    .Select(m => new {Method = m.Name, Controller = m.DeclaringType.Name}).ToList();

修改此查询以获取ApiControllers。

然后假设您正在使用NHibernate事务并在BeginRequest中打开它并在EndRequest中关闭它,然后整理AfterTransactionCompletion中的所有数据。