如题,需要对拦截到的ef语句进行数据库入库操作,
我调试发现,currentDB.Entry(aLog).State = EntityState.Added; currentDB.Set<AuditLog>().Add(aLog); currentDB.SaveChangesAsync(); 并没有发生死循环。
但是这个没报错 也没有插入数据库。不知道为什么
/// <summary> /// 数据库执行拦截 /// </summary> public class EFIntercepterLogging : DbCommandInterceptor { private readonly Stopwatch _stopwatch = new Stopwatch(); public override void ScalarExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<object> interceptionContext) { base.ScalarExecuting(command, interceptionContext); _stopwatch.Restart(); } public override void ScalarExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<object> interceptionContext) { _stopwatch.Stop(); AuditLog aLog = InitLog(command); IDbContext currentDB = (IDbContext)interceptionContext.DbContexts.Where(q => q.GetType() == typeof(EFContext)).FirstOrDefault(); if (aLog != null) { if (interceptionContext.Exception != null) { aLog.SqlQuery = (string.Format("Exception:{1} \r\n --> Error executing command: {0}", command.CommandText, interceptionContext.Exception.ToString())); } else { aLog.SqlQuery = (string.Format("\r\n执行时间:{0} 毫秒\r\n-->ScalarExecuted.Command:{1}\r\n", _stopwatch.ElapsedMilliseconds, command.CommandText)); } if (currentDB != null) { currentDB.Entry(aLog).State = EntityState.Added; currentDB.Set<AuditLog>().Add(aLog); currentDB.SaveChangesAsync(); } } base.ScalarExecuted(command, interceptionContext); } public override void NonQueryExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<int> interceptionContext) { base.NonQueryExecuting(command, interceptionContext); _stopwatch.Restart(); } public override void NonQueryExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<int> interceptionContext) { _stopwatch.Stop(); AuditLog aLog = InitLog(command); IDbContext currentDB = (IDbContext)interceptionContext.DbContexts.Where(q => q.GetType() == typeof(EFContext)).FirstOrDefault(); if (aLog != null) { if (interceptionContext.Exception != null) { aLog.SqlQuery = (string.Format("Exception:{1} \r\n --> Error executing command:\r\n {0}", command.CommandText, interceptionContext.Exception.ToString())); } else { aLog.SqlQuery = (string.Format("\r\n执行时间:{0} 毫秒\r\n-->NonQueryExecuted.Command:\r\n{1}", _stopwatch.ElapsedMilliseconds, command.CommandText)); } if (currentDB != null) { currentDB.Entry(aLog).State = EntityState.Added; currentDB.Set<AuditLog>().Add(aLog); currentDB.SaveChangesAsync(); } } base.NonQueryExecuted(command, interceptionContext); } public override void ReaderExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<System.Data.Common.DbDataReader> interceptionContext) { base.ReaderExecuting(command, interceptionContext); _stopwatch.Restart(); } public override void ReaderExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<System.Data.Common.DbDataReader> interceptionContext) { _stopwatch.Stop(); IDbContext currentDB = (IDbContext)interceptionContext.DbContexts.Where(q=>q.GetType() == typeof(EFContext)).FirstOrDefault(); AuditLog aLog = InitLog(command); if (aLog != null) { if (interceptionContext.Exception != null) { aLog.SqlQuery = (string.Format("Exception:{1} \r\n --> Error executing command:\r\n {0}", command.CommandText, interceptionContext.Exception.ToString())); } else { aLog.SqlQuery = (string.Format("\r\n执行时间:{0} 毫秒 \r\n -->ReaderExecuted.Command:\r\n{1}", _stopwatch.ElapsedMilliseconds, command.CommandText)); } //repo.Insert<AuditLog>(aLog); //repo.SaveChanges(); if (currentDB != null) { currentDB.Entry(aLog).State = EntityState.Added; currentDB.Set<AuditLog>().Add(aLog); currentDB.SaveChangesAsync(); } } base.ReaderExecuted(command, interceptionContext); } private AuditLog InitLog(System.Data.Common.DbCommand command) { AuditLog log = new AuditLog(); HttpContextBase context = new HttpContextWrapper(HttpContext.Current); RouteData rd = RouteTable.Routes.GetRouteData(context); if (rd != null) { string controllerName = rd.GetRequiredString("controller"); string actionName = rd.GetRequiredString("action"); string userName = HttpContext.Current.User.Identity.Name; string parms = ""; if(command!=null) { foreach(DbParameter parm in command.Parameters) { parms += string.Format(" 参数名:{0},值:{1};",parm.ParameterName,parm.Value); } } //排除审计控制器自身 以及日志插入自身 if (actionName.Contains(SystemConsts.ExceptedController_Audit) || command.CommandText.Contains(SystemConsts.ExceptedTable_AuditLog)) return null; log.Controller = controllerName; log.Action = actionName; log.StartTime = DateTime.Now; log.EndTime = DateTime.Now; log.AuditAccount = userName; // log.IP = IPHelper.GetRealIP(); log.Parameters = parms; } return log; } }
分好高。。。。。。
你在 NonQueryExecuted里面
currentDB.Set<AuditLog>().Add(aLog); currentDB.SaveChangesAsync();
那SaveChangesAsync又触发NonQueryExecuted,又接着插入,又触发。不就死循环拉。对不
有解决办法吗?求指点
@王庆东mas:
伪代码:
if(current thread data .xx==true)
return;
current thread data .xx=true
currentDB.SaveChangesAsync();
currentthread data.xx=false
@czd890: 我调试发现,currentDB.Entry(aLog).State = EntityState.Added; currentDB.Set<AuditLog>().Add(aLog); currentDB.SaveChangesAsync(); 并没有发生死循环。
但是这个没报错 也没有插入数据库。不知道为什么。
大神可以把我代码 复制了去帮我试下 ,呵呵
@王庆东mas:
还有这种语句。ExecuteSqlCommandAsync。在然后。不要用async测试。异步了。
@czd890: 没懂哈,问题依旧没解决==,不知道是拿到的CurrentDb 是还没打开连接还是啥?
@王庆东mas:
if(current thread data .xx==true)
return;
current thread data .xx=true
currentDB.ExecuteSqlCommand("insert into auditlog values ('s','3','ff')", null);
currentDB.SaveChanges();
currentthread data.xx=false
@czd890: 不是死循环问题阿啊啊啊。不信你测试
@王庆东mas:
不是死循环,能堆栈溢出啊,也是醉了
@czd890: 堆栈溢出是因为:currentDB.ExecuteSqlCommand(" delete from auditlog ", new object[] { });我把他删了。
问题是这个:
我调试发现,currentDB.Entry(aLog).State = EntityState.Added; currentDB.Set<AuditLog>().Add(aLog); currentDB.SaveChangesAsync(); 并没有发生死循环。
但是这个没报错 也没有插入数据库。不知道为什么
--
哎---
@王庆东mas: currentDB.SaveChanges();
@czd890: 未解决。。你把代码复制一下 试试就知道了。
@王庆东mas:
代码copy做个demo出来呀