溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

在.net中使用EF Core實(shí)現(xiàn)在控制臺(tái)中生成SQL語(yǔ)句

發(fā)布時(shí)間:2020-11-06 17:00:30 來(lái)源:億速云 閱讀:385 作者:Leah 欄目:開(kāi)發(fā)技術(shù)

今天就跟大家聊聊有關(guān)在.net中使用EF Core實(shí)現(xiàn)在控制臺(tái)中生成SQL語(yǔ)句,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

前言

筆者最近在開(kā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語(yǔ)句是非常關(guān)鍵的。那么除了使用第三方工具,如何查看EF Core生成的SQL語(yǔ)句呢?這里筆者將給出一個(gè)基于.NET Core內(nèi)置日志組件的實(shí)現(xiàn)方式。

創(chuàng)建一個(gè)實(shí)例項(xiàng)目

我們首先建一個(gè)控制臺(tái)程序,在主程序中我們編寫(xiě)了一個(gè)最簡(jiǎn)單的EF查詢(xún)。

  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ù)庫(kù),并在項(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語(yǔ)句輸出到控制臺(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的代碼非常的簡(jiǎn)單,就是直接返回一個(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格式化了日志信息。

最后我們還需要將自定義的日志處理類(lèi)和EF Core集成起來(lái)。這里我們需要復(fù)寫(xiě)上下文類(lèi)的OnConfiguring方法。在其中通過(guò)UseLoggerFactory方法,將我們自定義的日志處理類(lèi)和EF Core的日志系統(tǒng)關(guān)聯(lián)起來(lái)。

	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)目,看一下效果。這里日志信息正確的顯示出來(lái)了。

在.net中使用EF Core實(shí)現(xiàn)在控制臺(tái)中生成SQL語(yǔ)句

PS: 如果項(xiàng)目中使用了通用主機(jī)或者ASP.NET Core, 你也可以在服務(wù)配置部分,通過(guò)DbContextOptions參數(shù)配置。

services.AddDbContext<MyDbContext>(options =>
       options.UseSqlServer(Configuration.GetConnectionString("MyDb"))
          .UseLoggerFactory(new LoggerFactory()));

如何去除無(wú)關(guān)日志?

在前面的步驟中,我們成功的輸出了查詢(xún)語(yǔ)句,但是有一個(gè)問(wèn)題是我們只想查看輸出的SQL語(yǔ)句,其他的信息我們都不想要,那么能不能去除掉這些無(wú)關(guān)日志呢?答案是肯定的。

我們可以在Log方法中,通過(guò)分類(lèi)名稱(chēng),只輸出Microsoft.EntityFrameworkCore.Database.Command分類(lèi)下的日志,該日志即生成的SQL語(yǔ)句部分。

   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 ();
    }
  }

這里我們也做了一些其他的操作,通過(guò)修改控制臺(tái)輸出文本的顏色,高亮了生成的SQL語(yǔ)句。重新啟動(dòng)項(xiàng)目之后,效果如下。

在.net中使用EF Core實(shí)現(xiàn)在控制臺(tái)中生成SQL語(yǔ)句

如何顯示敏感數(shù)據(jù)?

這里看似我們已經(jīng)完成了EF Core的語(yǔ)句輸出,但是在實(shí)際使用中,你還會(huì)遇到另外一個(gè)問(wèn)題。

下面我們修改一下我們的主程序,我們嘗試插入一條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é)果。

在.net中使用EF Core實(shí)現(xiàn)在控制臺(tái)中生成SQL語(yǔ)句

這里你可能會(huì)問(wèn)為什么不顯示@p0, @p1參數(shù)的值。這里是原因是為了保護(hù)敏感數(shù)據(jù),EF Core默認(rèn)關(guān)閉的敏感數(shù)據(jù)的顯示配置,如果你想要查看敏感數(shù)據(jù),你需要通過(guò)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中使用EF Core實(shí)現(xiàn)在控制臺(tái)中生成SQL語(yǔ)句

看完上述內(nèi)容,你們對(duì)在.net中使用EF Core實(shí)現(xiàn)在控制臺(tái)中生成SQL語(yǔ)句有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI