首页 新闻 赞助 找找看

现在有这么一个需求,以AOP形式对 指定的Action进行Sql语句拦截记录。

0
悬赏园豆:10 [已解决问题] 解决于 2017-06-01 16:12
 现在有这么一个需求,以AOP形式控制 那些Action进行Sql语句拦截记录。
但是问题是拦截用的DbCommandInterceptor 和 Action这些不在同层。
如何实现这个需求阿 。
这是EF底层拦截器,已经注入到上下文了。
  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();
            if (interceptionContext.Exception != null)
            {
                Trace.TraceError("Exception:{1} \r\n --> Error executing command: {0}", command.CommandText, interceptionContext.Exception.ToString());
            }
            else
            {
                Trace.TraceInformation("\r\n执行时间:{0} 毫秒\r\n-->ScalarExecuted.Command:{1}\r\n", _stopwatch.ElapsedMilliseconds, command.CommandText);
            }
            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();
            if (interceptionContext.Exception != null)
            {
                Trace.TraceError("Exception:{1} \r\n --> Error executing command:\r\n {0}", command.CommandText, interceptionContext.Exception.ToString());
            }
            else
            {
                Trace.TraceInformation("\r\n执行时间:{0} 毫秒\r\n-->NonQueryExecuted.Command:\r\n{1}", _stopwatch.ElapsedMilliseconds, command.CommandText);
            }
            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();
            if (interceptionContext.Exception != null)
            {
                Trace.TraceError("Exception:{1} \r\n --> Error executing command:\r\n {0}", command.CommandText, interceptionContext.Exception.ToString());
            }
            else
            {
                Trace.TraceInformation("\r\n执行时间:{0} 毫秒 \r\n -->ReaderExecuted.Command:\r\n{1}", _stopwatch.ElapsedMilliseconds, command.CommandText);
            }
            base.ReaderExecuted(command, interceptionContext);
        }
    }
View Code

这是前段的controller

复制代码
  //要在这 控制这个action进行ef的sql语句拦截,怎么实现?
        // GET: /Account/Login
        [AllowAnonymous]
        public ActionResult Login(string returnUrl)
        {
            ViewBag.ReturnUrl = returnUrl;
            return View();
        }
复制代码

如上面所述。

只对Login这个Action进行 ef拦截sql,怎么实现?

王庆东mas的主页 王庆东mas | 初学一级 | 园豆:4
提问于:2017-05-19 11:14
< >
分享
最佳答案
0

在ef拦截里把他放到请求生命周期中的一个地方比如线程静态变量.过滤器里.查一下.

收获园豆:10
吴瑞祥 | 高人七级 |园豆:29449 | 2017-05-19 11:21

 可以给一个参考吗?吴大大

王庆东mas | 园豆:4 (初学一级) | 2017-05-19 11:25

@王庆东mas: 别..

不是已经在ef拦截了.最简单的法子是:写一个过滤器.然后过滤器里定义一个线程静态list<string> sqllog;

然后在ef拦截里往这个静态数组里追加sql.然后拦截器的action执行结束事件里把sqllog使用后清空.

 

吴瑞祥 | 园豆:29449 (高人七级) | 2017-05-19 11:30

@吴瑞祥: 重点是这个:在ef拦截里往这个静态数组里追加sql.    互相引用貌似不行吧

王庆东mas | 园豆:4 (初学一级) | 2017-05-19 13:11

@王庆东mas: 你那个ef拦截是在另一个层写的吗?

吴瑞祥 | 园豆:29449 (高人七级) | 2017-05-19 13:15

@吴瑞祥: 是的,是在数据库操作层。把 下面的类在 ef上下文初始化时候注入。

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();
            if (interceptionContext.Exception != null)
            {
                Trace.TraceError("Exception:{1} \r\n --> Error executing command: {0}", command.CommandText, interceptionContext.Exception.ToString());
            }
            else
            {
                Trace.TraceInformation("\r\n执行时间:{0} 毫秒\r\n-->ScalarExecuted.Command:{1}\r\n", _stopwatch.ElapsedMilliseconds, command.CommandText);
            }
            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();
            if (interceptionContext.Exception != null)
            {
                Trace.TraceError("Exception:{1} \r\n --> Error executing command:\r\n {0}", command.CommandText, interceptionContext.Exception.ToString());
            }
            else
            {
                Trace.TraceInformation("\r\n执行时间:{0} 毫秒\r\n-->NonQueryExecuted.Command:\r\n{1}", _stopwatch.ElapsedMilliseconds, command.CommandText);
            }
            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();
            if (interceptionContext.Exception != null)
            {
                Trace.TraceError("Exception:{1} \r\n --> Error executing command:\r\n {0}", command.CommandText, interceptionContext.Exception.ToString());
            }
            else
            {
                Trace.TraceInformation("\r\n执行时间:{0} 毫秒 \r\n -->ReaderExecuted.Command:\r\n{1}", _stopwatch.ElapsedMilliseconds, command.CommandText);
            }
            base.ReaderExecuted(command, interceptionContext);
        }
    }
View Code

这里就没法 取往mvc前段层传数据了。

王庆东mas | 园豆:4 (初学一级) | 2017-05-19 13:17

@王庆东mas: 那就在ef拦截器里弄个线程静态数组.

在过滤器里访问他.

吴瑞祥 | 园豆:29449 (高人七级) | 2017-05-19 13:18

@吴瑞祥: 过滤器和 ef层中间 还隔了一层 service层,不好搞。 哭。。

王庆东mas | 园豆:4 (初学一级) | 2017-05-19 13:19

@王庆东mas: 也应该可以访问的吧.反正思路是这样的.不嫌麻烦你再加一层代理也可以.

吴瑞祥 | 园豆:29449 (高人七级) | 2017-05-19 13:20

@吴瑞祥: 谢谢了

王庆东mas | 园豆:4 (初学一级) | 2017-05-19 13:22
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册