互联网技术 · 2024年2月12日

显示EF Core生成的SQL语句在控制台中的实用技巧

这篇文章主要介绍了如何将EF Core生成的SQL语句显示在控制台中,帮助大家更好的理解和学习.net core,感兴趣的朋友可以了解下

前言

笔者最近在开发和维护一个.NET Core项目,其中使用几个非常有意思的.NET Core相关的扩展,在此总结整理一下。

EF Core性能调优

如果你的项目中使用了EF Core, 且正在处于性能调优阶段,那么了解EF Core生成的SQL语句是非常关键的。那么除了使用第三方工具,如何查看EF Core生成的SQL语句呢?这里笔者将给出一个基于.NET Core内置日志组件的实现方式。

创建一个实例项目

我们首先建一个控制台程序,在主程序中我们编写了一个最简单的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();
      }
    }
  }

这里为了演示,我们提前创建了一个MySql数据库,并在项目中创建了一个对应的EF Core上下文。当前上下文中只有一个User实体,该实体只有2个属性UserId和UserName。

  public class MyDbContext : DbContext {

    public MyDbContext (DbContextOptions<MyDbContext> options) : base (options) {

    }

    public DbSet<User> Users { get; set; }
  }

如何生成的SQL语句输出到控制台?

.NET Core中提供了非常完善的日志接口。这里为了和.NET Core的日志接口集成,我们需要实现2个接口,一个是日志提供器接口ILoggerProvider, 一个是日志接口ILogger

EFLoggerProvider.cs

  public class EFLoggerProvider : ILoggerProvider {
    public ILogger CreateLogger (string categoryName) => new EFLogger (categoryName);
    public void Dispose () { }
  }

EFLoggerProvider的代码非常的简单,就是直接返回一个我们后续创建的EFLogger对象。

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

这里我们主要使用了内置的formatter格式化了日志信息。

最后我们还需要将自定义的日志处理类和EF Core集成起来。这里我们需要复写上下文类的OnConfiguring方法。在其中通过UseLoggerFactory方法,将我们自定义的日志处理类和EF Core的日志系统关联起来。

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

下面我们启动项目,看一下效果。这里日志信息正确的显示出来了。

.net core实用技巧——将EF Core生成的SQL语句显示在控制台中

PS: 如果项目中使用了通用主机或者ASP.NET Core, 你也可以在服务配置部分,通过DbContextOptions参数配置。

如何去除无关日志?

在前面的步骤中,我们成功的输出了查询语句,但是有一个问题是我们只想查看输出的SQL语句,其他的信息我们都不想要,那么能不能去除掉这些无关日志呢?答案是肯定的。

我们可以在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;
  &

OpenMagic API

Need more than content? Move into the product flow.

If you are here for model access, pricing, developer docs, or the future API console, the dedicated product path now lives on api.openmagic.ai.

登录免费注册