前言
笔者最近在开发和维护一个.NET Core项目,其中使用几个非常有意思的.NET Core相关的扩展,在此总结整理一下。
EF Core性能调优
如果你的项目中使用了EF Core, 且正在处于性能调优阶段,那么了解EF Core生成的SQL语句是非常关键的。那么除了使用第三方工具,如何查看EF Core生成的SQL语句呢?这里笔者将给出一个基于.NET Core内置日志组件的实现方式。
创建一个实例项目
我们首先建一个控制台程序,在主程序中我们编写了一个最简单的EF查询。
| 
								1
 
								2
 
								3
 
								4
 
								5
 
								6
 
								7
 
								8
 
								9
 
								10
 
								11
 
								12
						 | classProgram {staticvoidMain (string[] args) {var dbOptionBuilder = newDbContextOptionsBuilder<MyDbContext>();dbOptionBuilder.UseMySql("server=localhost;port=3306;database=EFCoreSampleDB;userid=root;pwd=a@12345");using(var dbContext = newMyDbContext(dbOptionBuilder.Options)) {var query = dbContext.Users.ToList();}}} | 
这里为了演示,我们提前创建了一个MySql数据库,并在项目中创建了一个对应的EF Core上下文。当前上下文中只有一个User实体,该实体只有2个属性UserId和UserName。
| 
								1
 
								2
 
								3
 
								4
 
								5
 
								6
 
								7
 
								8
						 | publicclassMyDbContext : DbContext {publicMyDbContext (DbContextOptions<MyDbContext> options) : base(options) {}publicDbSet<User> Users { get; set; }} | 
| 
								1
 
								2
 
								3
 
								4
 
								5
 
								6
						 | publicclassUser{[Key]publicGuid UserId { get; set;}publicstringUserName { get; set;}} | 
.NET Core中提供了非常完善的日志接口。这里为了和.NET Core的日志接口集成,我们需要实现2个接口,一个是日志提供器接口ILoggerProvider, 一个是日志接口ILogger
EFLoggerProvider.cs
| 
								1
 
								2
 
								3
 
								4
						 | publicclassEFLoggerProvider : ILoggerProvider {publicILogger CreateLogger (stringcategoryName) => newEFLogger (categoryName);publicvoidDispose () { }} | 
EFLoggerProvider的代码非常的简单,就是直接返回一个我们后续创建的EFLogger对象。
EFLogger.cs
| 
								1
 
								2
 
								3
 
								4
 
								5
 
								6
 
								7
 
								8
 
								9
 
								10
 
								11
 
								12
 
								13
 
								14
 
								15
 
								16
 
								17
 
								18
 
								19
 
								20
						 | publicclassEFLogger : ILogger {privatereadonlystringcategoryName;publicEFLogger (stringcategoryName) => this.categoryName = categoryName;publicboolIsEnabled (LogLevel logLevel) => true;publicvoidLog<TState> (LogLevel logLevel, EventId eventId,TState state, Exception exception, Func<TState, Exception, string> formatter) {var logContent = formatter (state, exception);Console.WriteLine ();Console.WriteLine (logContent);}}publicIDisposable BeginScope<TState> (TState state) => null;} | 
这里我们主要使用了内置的formatter格式化了日志信息。
最后我们还需要将自定义的日志处理类和EF Core集成起来。这里我们需要复写上下文类的OnConfiguring方法。在其中通过UseLoggerFactory方法,将我们自定义的日志处理类和EF Core的日志系统关联起来。
| 
								1
 
								2
 
								3
 
								4
 
								5
 
								6
 
								7
 
								8
 
								9
 
								10
 
								11
 
								12
 
								13
 
								14
 
								15
 
								16
 
								17
						 | publicclassMyDbContext : DbContext {publicMyDbContext (DbContextOptions<MyDbContext> options) : base(options) {}protectedoverridevoidOnConfiguring(DbContextOptionsBuilder optionsBuilder) {var loggerFactory = newLoggerFactory ();loggerFactory.AddProvider(newEFLoggerProvider());optionsBuilder.UseLoggerFactory(loggerFactory);base.OnConfiguring(optionsBuilder);}publicDbSet<User> Users { get; set; }} | 
下面我们启动项目,看一下效果。这里日志信息正确的显示出来了。
PS: 如果项目中使用了通用主机或者ASP.NET Core, 你也可以在服务配置部分,通过DbContextOptions参数配置。
| 
								1
 
								2
 
								3
						 | services.AddDbContext<MyDbContext>(options =>options.UseSqlServer(Configuration.GetConnectionString("MyDb")).UseLoggerFactory(newLoggerFactory())); | 
如何去除无关日志?
在前面的步骤中,我们成功的输出了查询语句,但是有一个问题是我们只想查看输出的SQL语句,其他的信息我们都不想要,那么能不能去除掉这些无关日志呢?答案是肯定的。
我们可以在Log方法中,通过分类名称,只输出Microsoft.EntityFrameworkCore.Database.Command分类下的日志,该日志即生成的SQL语句部分。
| 
								1
 
								2
 
								3
 
								4
 
								5
 
								6
 
								7
 
								8
 
								9
 
								10
 
								11
 
								12
 
								13
 
								14
 
								15
 
								16
 
								17
						 | publicvoidLog<TState> (LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter){if(categoryName == DbLoggerCategory.Database.Command.Name &&logLevel == LogLevel.Information) {var logContent = formatter (state, exception);Console.WriteLine ();Console.ForegroundColor = ConsoleColor.Green;Console.WriteLine (logContent);Console.ResetColor ();}} | 
这里我们也做了一些其他的操作,通过修改控制台输出文本的颜色,高亮了生成的SQL语句。重新启动项目之后,效果如下。
如何显示敏感数据?
这里看似我们已经完成了EF Core的语句输出,但是在实际使用中,你还会遇到另外一个问题。
下面我们修改一下我们的主程序,我们尝试插入一条User信息。
| 
								1
 
								2
 
								3
 
								4
 
								5
 
								6
 
								7
 
								8
 
								9
 
								10
 
								11
 
								12
						 | classProgram {staticvoidMain (string[] args) {var dbOptionBuilder = newDbContextOptionsBuilder<MyDbContext> ();dbOptionBuilder.UseMySql ("server=localhost;port=3306;database=EFCoreSampleDB;userid=root;pwd=a@12345");using(var dbContext = newMyDbContext (dbOptionBuilder.Options)) {dbContext.Users.Add(newUser { UserId = Guid.NewGuid(), UserName = "Lamond Lu"});dbContext.SaveChanges();}}} | 
重新运行程序,你会得到一下结果。
这里你可能会问为什么不显示@p0, @p1参数的值。这里是原因是为了保护敏感数据,EF Core默认关闭的敏感数据的显示配置,如果你想要查看敏感数据,你需要通过DbContextOptionsBuilder对象的EnableSensitiveDataLogging方法修改敏感数据日志配置。
| 
								1
 
								2
 
								3
 
								4
 
								5
 
								6
 
								7
 
								8
						 | protectedoverridevoidOnConfiguring (DbContextOptionsBuilder optionsBuilder) {var loggerFactory = newLoggerFactory ();loggerFactory.AddProvider (newEFLoggerProvider ());optionsBuilder.EnableSensitiveDataLogging (true);optionsBuilder.UseLoggerFactory (loggerFactory);base.OnConfiguring (optionsBuilder);} | 
重新启动项目之后,你就能看到@p0, @p1参数的值了。
以上就是.net core实用技巧——将EF Core生成的SQL语句显示在控制台中的详细内容,更多关于.net core实用技巧的资料请关注快网idc其它相关文章!
原文链接:https://www.cnblogs.com/lwqlun/p/13551149.html
相关文章
- 个人网站服务器域名解析设置指南:从购买到绑定全流程 2025-06-10
- 个人网站搭建:如何挑选具有弹性扩展能力的服务器? 2025-06-10
- 个人服务器网站搭建:如何选择适合自己的建站程序或框架? 2025-06-10
- 64M VPS建站:能否支持高流量网站运行? 2025-06-10
- 64M VPS建站:怎样选择合适的域名和SSL证书? 2025-06-10
- 2025-07-10 怎样使用阿里云的安全工具进行服务器漏洞扫描和修复?
- 2025-07-10 怎样使用命令行工具优化Linux云服务器的Ping性能?
- 2025-07-10 怎样使用Xshell连接华为云服务器,实现高效远程管理?
- 2025-07-10 怎样利用云服务器D盘搭建稳定、高效的网站托管环境?
- 2025-07-10 怎样使用阿里云的安全组功能来增强服务器防火墙的安全性?
快网idc优惠网
QQ交流群
- 
            PHPCMS V9跨站调用推荐位出现URL连接为空问题的解决方法 2025-05-29 32
- 
            2025-05-29 83
- 
            2025-05-27 62
- 
            2025-05-25 46
- 
            2025-05-25 28
 
        




 
    		 
            	 
															 
         
         
        
 
                        