陋室铭
永远也不要停下学习的脚步(大道至简至易)

posts - 2169,comments - 570,views - 413万

Entity Framework在使用时,很多时间操纵的是Model,并没有写sql语句,有时候为了调试或优化等,又需要追踪Entity framework自动生成的sql(最好还能记录起来,方便出错时排查)

方式一:

通过System.Data.Entity.DataBase.Log属性指定一个无返回值的委托,来实现记录日志的功能

复制代码
复制代码
public partial class EFContext<T> : DbContext where T : class
    {
        public EFContext(): base("name=MyConnectionString")
        {
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            Database.SetInitializer<EFContext<T>> (null);

            Database.Log = log => File.AppendAllText("ef.log",string.Format("{0}{1}{2}", DateTime.Now, Environment.NewLine, log));

            modelBuilder.Configurations.Add(new MemberMap());
            modelBuilder.Configurations.Add(new RoleMap());
            base.OnModelCreating(modelBuilder);
        }

        
        public DbSet<T> Table { get; set; }

        public IQueryable<T> GetList(Expression<Func<T,bool>> where)
        {
            return this.Table.Where(where);
        }
    }
复制代码
复制代码

其中:Database.Log = log => File.AppendAllText("ef.log",string.Format("{0}{1}{2}", DateTime.Now, Environment.NewLine, log)); 设置写入日志

控制台代码:

复制代码
EFContext<Member> efMemberContext = new EFContext<Member>();
var memberSet = efMemberContext.Set<Member>().Include("Role");

var memberList = memberSet.OrderBy(m => new { m.RoleId, m.Name });
foreach (Member item in memberList)
{
    Console.WriteLine("{0},Role:{1}",item.Name,item.Role.Name);
}
View Code
复制代码

运行程序后,打开ef.log文件,发现记录了日志

 

方式二:自定义一个类,继承于DbCommandInterceptor,重写下面几个方法

复制代码
public class EFDbCommandInterceptor : DbCommandInterceptor
    {
        /// <summary>
        /// 计时器
        /// </summary>
        public volatile Stopwatch watch = new Stopwatch();

        public override void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
        {
            base.NonQueryExecuting(command, interceptionContext);
            watch.Restart();
        }

        public override void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
        {
            watch.Stop();
            if (interceptionContext.Exception != null)
            {
                WriteLog(string.Format("Exception:{1} \r\n --> Error executing command: {0}", command.CommandText, interceptionContext.Exception.ToString()));
            }
            else
            {
                WriteLog(string.Format("\r\n执行时间:{0} 毫秒\r\n-->ScalarExecuted.Command:{1}\r\n", watch.ElapsedMilliseconds, command.CommandText));
            }
            base.NonQueryExecuted(command, interceptionContext);
        }

        public override void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
        {
            base.ScalarExecuting(command, interceptionContext);
            watch.Restart();
        }

        public override void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
        {
            watch.Stop();
            if (interceptionContext.Exception != null)
            {
                WriteLog(string.Format("Exception:{1} \r\n --> Error executing command: {0}", command.CommandText, interceptionContext.Exception.ToString()));
            }
            else
            {
                WriteLog(string.Format("\r\n执行时间:{0} 毫秒\r\n-->ScalarExecuted.Command:{1}\r\n", watch.ElapsedMilliseconds, command.CommandText));
            }
            base.ScalarExecuted(command, interceptionContext);
        }

        public override void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
        {
            base.ReaderExecuting(command, interceptionContext);
            watch.Restart();
        }

        public override void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
        {
            watch.Stop();
            if (interceptionContext.Exception != null)
            {
                WriteLog(string.Format("Exception:{1} \r\n --> Error executing command: {0}", command.CommandText, interceptionContext.Exception.ToString()));
            }
            else
            {
                WriteLog(string.Format("\r\n执行时间:{0} 毫秒\r\n-->ScalarExecuted.Command:{1}\r\n", watch.ElapsedMilliseconds, command.CommandText));
            }
            base.ReaderExecuted(command, interceptionContext);
        }
        /// <summary>
        /// 记录日志
        /// </summary>
        /// <param name="msg">消息</param>
        private void WriteLog(string msg)
        {
            //指定true表示追加
            using (TextWriter writer = new StreamWriter("Db.log",true))
            {
                writer.WriteLine(msg);   
            }
        }
    }
View Code
复制代码
复制代码
public partial class EFContext<T> : DbContext where T : class
    {
        public EFContext(): base("name=MyConnectionString")
        {
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            Database.SetInitializer<EFContext<T>> (null);

            //Database.Log = log => File.AppendAllText("ef.log",string.Format("{0}{1}{2}", DateTime.Now, Environment.NewLine, log));

            DbInterception.Add(new EFDbCommandInterceptor());

            modelBuilder.Configurations.Add(new MemberMap());
            modelBuilder.Configurations.Add(new RoleMap());
            base.OnModelCreating(modelBuilder);
        }

        
        public DbSet<T> Table { get; set; }

        public IQueryable<T> GetList(Expression<Func<T,bool>> where)
        {
            return this.Table.Where(where);
        }
    }
View Code
复制代码

其中DbInterception.Add(new EFDbCommandInterceptor());  设置日志记录

还是刚才的控制台代码,运行程序,打开Db.log

 

 

另外还有其它方法获取Entity Framework 执行的sql代码,比如SQL Server Profiler工具,不过这个不属于通过Entity Framework代码去配置,所以在此就不再赘述

posted on   宏宇  阅读(376)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
历史上的今天:
2007-03-27 IE的一个特效 直接复制到地址栏运行
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示