.net core实用技巧——将EF Core生成的SQL语句显示在控制台中
前言
笔者最近在开发和维护一个.NETCore项目,其中使用几个非常有意思的.NETCore相关的扩展,在此总结整理一下。
EFCore性能调优
如果你的项目中使用了EFCore,且正在处于性能调优阶段,那么了解EFCore生成的SQL语句是非常关键的。那么除了使用第三方工具,如何查看EFCore生成的SQL语句呢?这里笔者将给出一个基于.NETCore内置日志组件的实现方式。
创建一个实例项目
我们首先建一个控制台程序,在主程序中我们编写了一个最简单的EF查询。
classProgram{ staticvoidMain(string[]args){ vardbOptionBuilder=newDbContextOptionsBuilder(); dbOptionBuilder .UseMySql("server=localhost;port=3306;database=EFCoreSampleDB;userid=root;pwd=a@12345"); using(vardbContext=newMyDbContext(dbOptionBuilder.Options)){ varquery=dbContext.Users.ToList(); } } }
这里为了演示,我们提前创建了一个MySql数据库,并在项目中创建了一个对应的EFCore上下文。当前上下文中只有一个User实体,该实体只有2个属性UserId和UserName。
publicclassMyDbContext:DbContext{ publicMyDbContext(DbContextOptionsoptions):base(options){ } publicDbSet Users{get;set;} }
publicclassUser { [Key] publicGuidUserId{get;set;} publicstringUserName{get;set;} }
如何生成的SQL语句输出到控制台?
.NETCore中提供了非常完善的日志接口。这里为了和.NETCore的日志接口集成,我们需要实现2个接口,一个是日志提供器接口ILoggerProvider,一个是日志接口ILogger
EFLoggerProvider.cs
publicclassEFLoggerProvider:ILoggerProvider{ publicILoggerCreateLogger(stringcategoryName)=>newEFLogger(categoryName); publicvoidDispose(){} }
EFLoggerProvider的代码非常的简单,就是直接返回一个我们后续创建的EFLogger对象。
EFLogger.cs
publicclassEFLogger:ILogger{ privatereadonlystringcategoryName; publicEFLogger(stringcategoryName)=>this.categoryName=categoryName; publicboolIsEnabled(LogLevellogLevel)=>true; publicvoidLog(LogLevellogLevel, EventIdeventId, TStatestate, Exceptionexception, Func formatter){ varlogContent=formatter(state,exception); Console.WriteLine(); Console.WriteLine(logContent); } } publicIDisposableBeginScope (TStatestate)=>null; }
这里我们主要使用了内置的formatter格式化了日志信息。
最后我们还需要将自定义的日志处理类和EFCore集成起来。这里我们需要复写上下文类的OnConfiguring方法。在其中通过UseLoggerFactory方法,将我们自定义的日志处理类和EFCore的日志系统关联起来。
publicclassMyDbContext:DbContext{ publicMyDbContext(DbContextOptionsoptions):base(options){ } protectedoverridevoidOnConfiguring(DbContextOptionsBuilderoptionsBuilder){ varloggerFactory=newLoggerFactory(); loggerFactory.AddProvider(newEFLoggerProvider()); optionsBuilder.UseLoggerFactory(loggerFactory); base.OnConfiguring(optionsBuilder); } publicDbSet Users{get;set;} }
下面我们启动项目,看一下效果。这里日志信息正确的显示出来了。
PS:如果项目中使用了通用主机或者ASP.NETCore,你也可以在服务配置部分,通过DbContextOptions参数配置。
services.AddDbContext(options=> options.UseSqlServer(Configuration.GetConnectionString("MyDb")) .UseLoggerFactory(newLoggerFactory()));
如何去除无关日志?
在前面的步骤中,我们成功的输出了查询语句,但是有一个问题是我们只想查看输出的SQL语句,其他的信息我们都不想要,那么能不能去除掉这些无关日志呢?答案是肯定的。
我们可以在Log方法中,通过分类名称,只输出Microsoft.EntityFrameworkCore.Database.Command分类下的日志,该日志即生成的SQL语句部分。
publicvoidLog(LogLevellogLevel, EventIdeventId, TStatestate, Exceptionexception, Func formatter) { if(categoryName==DbLoggerCategory.Database.Command.Name&& logLevel==LogLevel.Information){ varlogContent=formatter(state,exception); Console.WriteLine(); Console.ForegroundColor=ConsoleColor.Green; Console.WriteLine(logContent); Console.ResetColor(); } }
这里我们也做了一些其他的操作,通过修改控制台输出文本的颜色,高亮了生成的SQL语句。重新启动项目之后,效果如下。
如何显示敏感数据?
这里看似我们已经完成了EFCore的语句输出,但是在实际使用中,你还会遇到另外一个问题。
下面我们修改一下我们的主程序,我们尝试插入一条User信息。
classProgram{ staticvoidMain(string[]args){ vardbOptionBuilder=newDbContextOptionsBuilder(); dbOptionBuilder.UseMySql("server=localhost;port=3306;database=EFCoreSampleDB;userid=root;pwd=a@12345"); using(vardbContext=newMyDbContext(dbOptionBuilder.Options)){ dbContext.Users.Add(newUser{UserId=Guid.NewGuid(),UserName="LamondLu"}); dbContext.SaveChanges(); } } }
重新运行程序,你会得到一下结果。
这里你可能会问为什么不显示@p0,@p1参数的值。这里是原因是为了保护敏感数据,EFCore默认关闭的敏感数据的显示配置,如果你想要查看敏感数据,你需要通过DbContextOptionsBuilder对象的EnableSensitiveDataLogging方法修改敏感数据日志配置。
protectedoverridevoidOnConfiguring(DbContextOptionsBuilderoptionsBuilder){ varloggerFactory=newLoggerFactory(); loggerFactory.AddProvider(newEFLoggerProvider()); optionsBuilder.EnableSensitiveDataLogging(true); optionsBuilder.UseLoggerFactory(loggerFactory); base.OnConfiguring(optionsBuilder); }
重新启动项目之后,你就能看到@p0,@p1参数的值了。
以上就是.netcore实用技巧——将EFCore生成的SQL语句显示在控制台中的详细内容,更多关于.netcore实用技巧的资料请关注毛票票其它相关文章!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。