.net core實(shí)用技巧——將EF Core生成的SQL語句顯示在控制臺(tái)中
前言
筆者最近在開發(fā)和維護(hù)一個(gè).NET Core項(xiàng)目,其中使用幾個(gè)非常有意思的.NET Core相關(guān)的擴(kuò)展,在此總結(jié)整理一下。
EF Core性能調(diào)優(yōu)
如果你的項(xiàng)目中使用了EF Core, 且正在處于性能調(diào)優(yōu)階段,那么了解EF Core生成的SQL語句是非常關(guān)鍵的。那么除了使用第三方工具,如何查看EF Core生成的SQL語句呢?這里筆者將給出一個(gè)基于.NET Core內(nèi)置日志組件的實(shí)現(xiàn)方式。
創(chuàng)建一個(gè)實(shí)例項(xiàng)目
我們首先建一個(gè)控制臺(tái)程序,在主程序中我們編寫了一個(gè)最簡單的EF查詢。
class Program { static void Main (string[] args) { var dbOptionBuilder = new DbContextOptionsBuilder<MyDbContext>(); dbOptionBuilder .UseMySql("server=localhost;port=3306;database=EFCoreSampleDB;userid=root;pwd=a@12345"); using (var dbContext = new MyDbContext(dbOptionBuilder.Options)) { var query = dbContext.Users.ToList(); } } }
這里為了演示,我們提前創(chuàng)建了一個(gè)MySql數(shù)據(jù)庫,并在項(xiàng)目中創(chuàng)建了一個(gè)對(duì)應(yīng)的EF Core上下文。當(dāng)前上下文中只有一個(gè)User實(shí)體,該實(shí)體只有2個(gè)屬性UserId和UserName。
public class MyDbContext : DbContext { public MyDbContext (DbContextOptions<MyDbContext> options) : base (options) { } public DbSet<User> Users { get; set; } }
public class User { [Key] public Guid UserId { get; set;} public string UserName { get; set;} }
如何生成的SQL語句輸出到控制臺(tái)?
.NET Core中提供了非常完善的日志接口。這里為了和.NET Core的日志接口集成,我們需要實(shí)現(xiàn)2個(gè)接口,一個(gè)是日志提供器接口ILoggerProvider, 一個(gè)是日志接口ILogger
EFLoggerProvider.cs
public class EFLoggerProvider : ILoggerProvider { public ILogger CreateLogger (string categoryName) => new EFLogger (categoryName); public void Dispose () { } }
EFLoggerProvider的代碼非常的簡單,就是直接返回一個(gè)我們后續(xù)創(chuàng)建的EFLogger對(duì)象。
EFLogger.cs
public class EFLogger : ILogger { private readonly string categoryName; public EFLogger (string categoryName) => this.categoryName = categoryName; public bool IsEnabled (LogLevel logLevel) => true; public void Log<TState> (LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) { var logContent = formatter (state, exception); Console.WriteLine (); Console.WriteLine (logContent); } } public IDisposable BeginScope<TState> (TState state) => null; }
這里我們主要使用了內(nèi)置的formatter格式化了日志信息。
最后我們還需要將自定義的日志處理類和EF Core集成起來。這里我們需要復(fù)寫上下文類的OnConfiguring方法。在其中通過UseLoggerFactory方法,將我們自定義的日志處理類和EF Core的日志系統(tǒng)關(guān)聯(lián)起來。
public class MyDbContext : DbContext { public MyDbContext (DbContextOptions<MyDbContext> options) : base (options) { } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { var loggerFactory = new LoggerFactory (); loggerFactory.AddProvider(new EFLoggerProvider()); optionsBuilder.UseLoggerFactory(loggerFactory); base.OnConfiguring(optionsBuilder); } public DbSet<User> Users { get; set; } }
下面我們啟動(dòng)項(xiàng)目,看一下效果。這里日志信息正確的顯示出來了。
PS: 如果項(xiàng)目中使用了通用主機(jī)或者ASP.NET Core, 你也可以在服務(wù)配置部分,通過DbContextOptions參數(shù)配置。
services.AddDbContext<MyDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MyDb")) .UseLoggerFactory(new LoggerFactory()));
如何去除無關(guān)日志?
在前面的步驟中,我們成功的輸出了查詢語句,但是有一個(gè)問題是我們只想查看輸出的SQL語句,其他的信息我們都不想要,那么能不能去除掉這些無關(guān)日志呢?答案是肯定的。
我們可以在Log方法中,通過分類名稱,只輸出Microsoft.EntityFrameworkCore.Database.Command分類下的日志,該日志即生成的SQL語句部分。
public void Log<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 (); } }
這里我們也做了一些其他的操作,通過修改控制臺(tái)輸出文本的顏色,高亮了生成的SQL語句。重新啟動(dòng)項(xiàng)目之后,效果如下。
如何顯示敏感數(shù)據(jù)?
這里看似我們已經(jīng)完成了EF Core的語句輸出,但是在實(shí)際使用中,你還會(huì)遇到另外一個(gè)問題。
下面我們修改一下我們的主程序,我們嘗試插入一條User信息。
class Program { static void Main (string[] args) { var dbOptionBuilder = new DbContextOptionsBuilder<MyDbContext> (); dbOptionBuilder.UseMySql ("server=localhost;port=3306;database=EFCoreSampleDB;userid=root;pwd=a@12345"); using (var dbContext = new MyDbContext (dbOptionBuilder.Options)) { dbContext.Users.Add(new User { UserId = Guid.NewGuid(), UserName = "Lamond Lu"}); dbContext.SaveChanges(); } } }
重新運(yùn)行程序,你會(huì)得到一下結(jié)果。
這里你可能會(huì)問為什么不顯示@p0, @p1參數(shù)的值。這里是原因是為了保護(hù)敏感數(shù)據(jù),EF Core默認(rèn)關(guān)閉的敏感數(shù)據(jù)的顯示配置,如果你想要查看敏感數(shù)據(jù),你需要通過DbContextOptionsBuilder對(duì)象的EnableSensitiveDataLogging方法修改敏感數(shù)據(jù)日志配置。
protected override void OnConfiguring (DbContextOptionsBuilder optionsBuilder) { var loggerFactory = new LoggerFactory (); loggerFactory.AddProvider (new EFLoggerProvider ()); optionsBuilder.EnableSensitiveDataLogging (true); optionsBuilder.UseLoggerFactory (loggerFactory); base.OnConfiguring (optionsBuilder); }
重新啟動(dòng)項(xiàng)目之后,你就能看到@p0, @p1參數(shù)的值了。
以上就是.net core實(shí)用技巧——將EF Core生成的SQL語句顯示在控制臺(tái)中的詳細(xì)內(nèi)容,更多關(guān)于.net core實(shí)用技巧的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- .net如何優(yōu)雅的使用EFCore實(shí)例詳解
- ASP.NET?Core?5.0中的Host.CreateDefaultBuilder執(zhí)行過程解析
- .Net Core中使用EFCore生成反向工程
- ASP.NET Core使用EF保存數(shù)據(jù)、級(jí)聯(lián)刪除和事務(wù)使用
- ASP.NET?Core使用EF查詢數(shù)據(jù)
- ASP.NET?Core使用EF創(chuàng)建模型(索引、備用鍵、繼承、支持字段)
- ASP.NET?Core使用EF?SQLite對(duì)數(shù)據(jù)庫增刪改查
- 詳解.Net Core 權(quán)限驗(yàn)證與授權(quán)(AuthorizeFilter、ActionFilterAttribute)
- 在.NET Core類庫中使用EF Core遷移數(shù)據(jù)庫到SQL Server的方法
- .net連接oracle的3種實(shí)現(xiàn)方法
- C#利用ODP.net連接Oracle數(shù)據(jù)庫的操作方法
- .Net使用EF Core框架連接Oracle的方法
相關(guān)文章
編寫的vs2005水晶報(bào)表程序在vs2008下正常使用的一些實(shí)現(xiàn)方法
以前用vs2005編寫的WEB程序,現(xiàn)在使用vs2008時(shí)總是出現(xiàn)水晶報(bào)表的錯(cuò)誤,不能使用。經(jīng)過本人實(shí)踐,總結(jié)一下錯(cuò)誤原因。2009-09-09vs2010根據(jù)字符串內(nèi)容添加斷點(diǎn)的方法介紹
這篇文章介紹了vs2010根據(jù)字符串內(nèi)容添加斷點(diǎn)的方法,有需要的朋友可以參考一下2013-08-08時(shí)間輕松學(xué)會(huì).NET Core操作ElasticSearch7的方法
這篇文章主要介紹了時(shí)間輕松學(xué)會(huì).NET Core操作ElasticSearch7,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04Visual Studio 2017中找回消失的“在瀏覽器中查看”命令
這篇文章主要為大家詳細(xì)介紹了如何在Visual Studio 2017中找回消失的“在瀏覽器中查看”命令,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03asp.net?core?中的Jwt(Json?Web?Token)的使用詳解
session不支持分布式并且在服務(wù)器存儲(chǔ)一份用戶登錄的信息,這份登錄信息會(huì)在響應(yīng)時(shí)傳遞給瀏覽器,告訴其保存為cookie,以便下次請(qǐng)求時(shí)發(fā)送給我們的應(yīng)用,這篇文章主要介紹了asp.net?core?中的Jwt(Json?Web?Token)的使用,需要的朋友可以參考下2022-10-10ASP.NET Core MVC如何實(shí)現(xiàn)運(yùn)行時(shí)動(dòng)態(tài)定義Controller類型
這篇文章主要介紹了ASP.NET Core MVC如何實(shí)現(xiàn)運(yùn)行時(shí)動(dòng)態(tài)定義Controller類型,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06ASP.NET Core使用Log4net實(shí)現(xiàn)日志記錄功能
這篇文章介紹了ASP.NET Core使用Log4net實(shí)現(xiàn)日志記錄功能的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03