我有一个带有控制器的旧版asp.net mvc项目,该控制器返回视图和一些Web api控制器。该数据库是ms sql。 ORM是NHibernate。 我想记录有多少查询进入数据库以执行某项操作。 像这样的东西
{namepage}, {controller}, {action} - {count of queries}
我认为可以通过全局过滤器来实现。 你能给我关于我该怎么做的想法吗?
答案 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中的所有数据。