四、EFCore系列之使用代码查看EFCore生成的Sql语句

一、使用日志记录

1.1 标准日志

1.1.1 静态日志工厂

1. 定义静态日志工厂:在MyDbContext类中直接定义一个静态只读的ILoggerFactory字段,并使用 LoggerFactory.Create方法进行初始化。

public static readonly ILoggerFactory loggerFactory = LoggerFactory.Create(builder =>
{
    builder.AddConsole(); // 输出到控制台
});

2.在 OnConfiguring 方法中使用日志工厂:在 OnConfiguring方法中调用 UseLoggerFactory方法,将日志工厂传递给 EF Core。

optionsBuilder.UseLoggerFactory(loggerFactory);

1.1.2 依赖注入实现日志工厂

确保 MyDbContext 接受 ILoggerFactory 作为构造函数的参数,并在 OnConfiguring 方法中使用它进行日志配置。

public class MyDbContext : DbContext
{
    // 使用代码查看Sql语句,标准日志
    // 1. 依赖注入实现日志工厂
    public readonly ILoggerFactory _loggerFactory;

    public MyDbContext(ILoggerFactory loggerFactory)
    {
        _loggerFactory = loggerFactory;
    }

    /// <summary>
    /// 配置数据库连接。
    /// </summary>
    /// <param name="optionsBuilder"></param>
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        base.OnConfiguring(optionsBuilder);
        // 1. 定义数据库连接字符串
        String connectionString = "";
        // 2. 指定数据库类型为 MySQL
        optionsBuilder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString));
        // 3. 配置日志
        optionsBuilder.UseLoggerFactory(_loggerFactory);
    }
}

使用 ServiceCollection 来配置日志记录服务,并将其传递给 MyDbContext。

private static void Main(string[] args)
{
    // 1. 创建服务集合
    ServiceCollection services = new();
    // 2. 添加日志服务
    services.AddLogging(logger => logger.AddConsole());
    // 3.构建服务提供者
    ServiceProvider sp = services.BuildServiceProvider();
    // 4. 获取日志工厂
    var logger = sp.GetService<ILoggerFactory>();
    // 5. 创建数据库上下文实例并传入日志工厂
    using (MyDbContext myDb = new(logger))
    {
        AddData(myDb);
    }
}
private static void AddData(MyDbContext myDb)
{
    // 1. 创建的数据库上下文实例
    Book book = new Book
    {
        Title = "C#入门",
        PubTime = DateTime.Now,
        Price = 99.99,
        AuthorName = "张三"
    };

    // 2. 将新创建的 Book 对象添加到 Books 集合中(逻辑上的添加)
    myDb.Books.Add(book);
    // 3. 提交更改,将数据保存到数据库中(实际的添加)
    myDb.SaveChanges();
}

1.2 简单日志

在数据库上下文的 OnConfiguring 方法中加入以下内容

optionsBuilder.LogTo(Console.WriteLine, LogLevel.Information);

二、ToQueryString()

  • 查询操作:通过 LINQ 表达式构建查询,并可以通过 ToQueryString() 方法查看生成的 SQL 查询语句。
  • 插入、更新或删除操作:不能使用 ToQueryString() 直接获取生成的 SQL 语句,但可以通过配置日志记录服务查询操作。
private static void Main(string[] args)
{
    using (MyDbContext myDb = new())
    {
        IQueryable<Book> result = myDb.Books.Where(b => b.Title == "C#入门");
        string sql = result.ToQueryString();
        Console.WriteLine(sql);
    }
}

        IQueryable<Book> result = myDb.Books.Where(b => b.Title == "C#入门"); 这行代码并没有立即执行数据库查询。这是因为EF采用了延迟加载的机制。

        具体来说,当你编写如myDb.Books.Where(b => b.Title == "C#入门")这样的LINQ查询时,EF并不会立刻去数据库执行这个查询。相反,它会构建一个表达式树(Expression Tree),这个表达式树描述了你想要执行的操作。只有当你进一步操作这个查询结果,比如调用 ToList()、FirstOrDefault() 等方法时,EF才会将这个表达式树转换为SQL语句,并发送到数据库执行。

总结:

  • myDb.Books.Where(b => b.Title == "C#入门") 构建了一个表达式树,描述了你想要执行的查询。
  • ToQueryString() 方法用于获取这个表达式树对应的SQL语句字符串。
  • 实际的数据库查询会在你尝试获取查询结果(如 ToList()、FirstOrDefault() 等)时才被执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值