当前位置: 首页 > news >正文

02020406 EF Core基础06-EF Core生成的SQL

02020406 EF Core基础06-EF Core生成的SQL

1. 通过代码查看EF Core的SQL语句(视频3-12)

1.1 方法1:标准日志
// 标准日志用法示例
public static readonly ILoggerFactory MyLoggerFactory= LoggerFactory.Create(builder => { builder.AddConsole(); });optionsBuilder.UseLoggerFactory(MyLoggerFactory);
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 需要安装的包
1. microsoft.entityframeworkcore.sqlserver -Version 5.0.4
2. microsoft.entityframeworkcore.tools -Version 5.0.4
3. install-package microsoft.extensions.logging.console -version 5.0.0
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// Dog.cs
namespace DBLogDemo
{public class Dog{public long Id { get; set; }public string Name { get; set; }}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// DbContext.cs
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;namespace DBLogDemo
{class MyDbContext : DbContext{private static ILoggerFactory loggerFactory = LoggerFactory.Create(b => b.AddConsole()); // @1public DbSet<Dog> Dogs { get; set; }protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){string connStr = "Server=.;Database=CoreDataDB;Trusted_Connection=True;MultipleActiveResultSets=true";optionsBuilder.UseSqlServer(connStr);optionsBuilder.UseLoggerFactory(loggerFactory); // @2}protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);}}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
using System;
using System.Threading.Tasks;namespace DBLogDemo
{class Program{static async Task Main(string[] args){using (MyDbContext ctx = new MyDbContext()){Dog d01 = new Dog();d01.Name = "abc";ctx.Dogs.Add(d01);await ctx.SaveChangesAsync();d01.Name = "abc";Console.WriteLine(d01.Id);}Console.ReadLine();}}
}控制台输出:
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]Entity Framework Core 5.0.4 initialized 'MyDbContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None
info: Microsoft.EntityFrameworkCore.Database.Command[20101]Executed DbCommand (31ms) [Parameters=[@p0='?' (Size = 4000)], CommandType='Text', CommandTimeout='30']SET NOCOUNT ON; // 标准SQL语句startINSERT INTO [Dogs] ([Name])VALUES (@p0);SELECT [Id]FROM [Dogs]WHERE @@ROWCOUNT = 1 AND [Id] = scope_identity(); // 标准SQL语句end
2 // Id值
1.2 方法2:简单日志
// 简单日志用法示例
optionsBuilder.LogTo(Console.WriteLine);
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 需要安装的包
1. microsoft.entityframeworkcore.sqlserver -version 5.0.4
2. microsoft.entityframeworkcore.tools -version 5.0.4
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// Dog.cs
namespace DBLogDemo
{public class Dog{public long Id { get; set; }public string Name { get; set; }}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// DbContext.cs
using Microsoft.EntityFrameworkCore;namespace DBLogDemo
{class MyDbContext : DbContext{public DbSet<Dog> Dogs { get; set; }protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){string connStr = "Server=.;Database=CoreDataDB;Trusted_Connection=True;MultipleActiveResultSets=true";optionsBuilder.UseSqlServer(connStr);optionsBuilder.LogTo( msg => {System.Console.WriteLine(msg);}); // LogTo参数为string形式的委托}protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);}}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// Program.cs
using System;
using System.Threading.Tasks;namespace DBLogDemo
{class Program{static async Task Main(string[] args){using (MyDbContext ctx = new MyDbContext()){Dog d01 = new Dog();d01.Name = "abc";ctx.Dogs.Add(d01);await ctx.SaveChangesAsync();d01.Name = "abc";Console.WriteLine(d01.Id);}Console.ReadLine();}}
}控制台输出:
info: 2025/9/21 20:38:14.997 CoreEventId.ContextInitialized[10403] (Microsoft.EntityFrameworkCore.Infrastructure)
...SaveChanges completed for 'MyDbContext' with 1 entities written to the database.
3 // Id值
dbug: 2025/9/21 20:38:15.510 CoreEventId.ContextDisposed[10407] (Microsoft.EntityFrameworkCore.Infrastructure)'MyDbContext' disposed.说明:
1. 用起来简单,但是看起来好多啊-_-。
2. 可以输出EF Core整个生命周期的日志信息。
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// DbContext.cs
using Microsoft.EntityFrameworkCore;namespace DBLogDemo
{class MyDbContext : DbContext{public DbSet<Dog> Dogs { get; set; }protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){string connStr = "Server=.;Database=CoreDataDB;Trusted_Connection=True;MultipleActiveResultSets=true";optionsBuilder.UseSqlServer(connStr);optionsBuilder.LogTo( msg => { if (!msg.Contains("CommandExecuting")) return; System.Console.WriteLine(msg);}); // 过滤信息,只要SQL语句部分。}protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);}}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// Program.csusing System;
using System.Threading.Tasks;namespace DBLogDemo
{class Program{static async Task Main(string[] args){using (MyDbContext ctx = new MyDbContext()){Dog d01 = new Dog();d01.Name = "abc";ctx.Dogs.Add(d01);await ctx.SaveChangesAsync();d01.Name = "abc";Console.WriteLine(d01.Id);}Console.ReadLine();}}
}控制台输出:
dbug: 2025/9/21 20:46:21.950 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)Executing DbCommand [Parameters=[@p0='?' (Size = 4000)], CommandType='Text', CommandTimeout='30']SET NOCOUNT ON;INSERT INTO [Dogs] ([Name])VALUES (@p0);SELECT [Id]FROM [Dogs]WHERE @@ROWCOUNT = 1 AND [Id] = scope_identity();
5说明:只输出SQL语句部分。
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// Program.cs,演示多条SQL语句。
using System;
using System.Linq;
using System.Threading.Tasks;namespace DBLogDemo
{class Program{static async Task Main(string[] args){using (MyDbContext ctx = new MyDbContext()){Dog d01 = new Dog();d01.Name = "abc";ctx.Dogs.Add(d01); // SQL语句1ctx.Dogs.Add(new Dog { Name = "Trump" }); // SQL语句2await ctx.SaveChangesAsync();Console.WriteLine(ctx.Dogs.Count()); // SQL语句3}Console.ReadLine();}}
}控制台输出:
dbug: 2025/9/21 20:52:51.558 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)Executing DbCommand [Parameters=[@p0='?' (Size = 4000)], CommandType='Text', CommandTimeout='30']SET NOCOUNT ON;INSERT INTO [Dogs] ([Name])VALUES (@p0);SELECT [Id]FROM [Dogs]WHERE @@ROWCOUNT = 1 AND [Id] = scope_identity();
dbug: 2025/9/21 20:52:51.624 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)Executing DbCommand [Parameters=[@p0='?' (Size = 4000)], CommandType='Text', CommandTimeout='30']SET NOCOUNT ON;INSERT INTO [Dogs] ([Name])VALUES (@p0);SELECT [Id]FROM [Dogs]WHERE @@ROWCOUNT = 1 AND [Id] = scope_identity();
dbug: 2025/9/21 20:52:51.854 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']SELECT COUNT(*)FROM [Dogs] AS [d]说明:过滤后每个SQL操作的语句都可以查到,如果SQL操作很多,那么输出很多个SQL语句,查起来会很麻烦。可以定向的找到所需要的SQL语句。
1.3 方法3:ToQueryString
1、上面两种方式无法直接得到一个操作的SQL语句,而且在操作很多的情况下,容易混乱。
2、EF Core的Where方法返回的是IQueryable类型,DbSet也实现了IQueryable接口。 IQueryable有扩展方法ToQueryString()可以获得SQL。
3、不需要真的执行查询才获取SQL语句;只能获取查询操作的。
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// Dog.cs
namespace DBLogDemo
{public class Dog{public long Id { get; set; } //主键public string Name { get; set; }//标题}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// MyDbContext
using Microsoft.EntityFrameworkCore;namespace DBLogDemo
{class MyDbContext : DbContext{public DbSet<Dog> Dogs { get; set; }protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){string connStr = "Server=.;Database=CoreDataDB;Trusted_Connection=True;MultipleActiveResultSets=true";optionsBuilder.UseSqlServer(connStr);}protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);}}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Threading.Tasks;namespace DBLogDemo
{class Program{static async Task Main(string[] args){using (MyDbContext ctx = new MyDbContext()){Dog d01 = new Dog();d01.Name = "abc";ctx.Dogs.Add(d01);ctx.Dogs.Add(new Dog { Name = "Trump" }); // 拿不到await ctx.SaveChangesAsync();Console.WriteLine(ctx.Dogs.Count()); // 拿不到IQueryable<Dog> dogs01 = ctx.Dogs.Where(d => d.Name.ToLower() == "Trump");string sql = dogs01.ToQueryString();Console.WriteLine("这就是我要的SQL语句:" + sql); // ToQueryStirng只能拿到查询操作的SQL语句/*foreach (var it in d02){Console.WriteLine(it.Id);}*/}Console.ReadLine();}}
}控制台输出:
13
SELECT [d].[Id], [d].[Name]
FROM [Dogs] AS [d]
WHERE LOWER([d].[Name]) = N'Trump'说明:
1. ToQueryString方法只能拿到查询操作的SQL语句,其它形式的SQL语句拿不到。
2. ToQueryString方法可以在不真的执行数据库查询的情形下直接拿到查询结果,后续课程会演示。
1.4 总结
  • 写测试性代码,用简单日志;
  • 正式需要记录SQL给审核人员或者排查故障,用标准日志;
  • 开发阶段,从繁杂的查询操作中立即看到SQL,用ToQueryString()。

2. 同样的LINQ被翻译为不同的SQL语句(视频3-13)

  • 本课跳过,目前只针对性的学习SQL Server。本机也没安装其它数据库,无法演示。
  • 后续用得到再补。

结尾

书籍:ASP.NET Core技术内幕与项目实战

视频:https://www.bilibili.com/video/BV1pK41137He

著:杨中科

ISBN:978-7-115-58657-5

版次:第1版

发行:人民邮电出版社

※敬请购买正版书籍,侵删请联系85863947@qq.com※

※本文章为看书或查阅资料而总结的笔记,仅供参考,如有错误请留言指正,谢谢!※

http://www.hskmm.com/?act=detail&tid=15157

相关文章:

  • Gemini-2.5-Flash-Image-Preview 与 GPT-4o 图像生成能力技术差异解析​ - 教程
  • 新学期每日总结(第2天)
  • 在CodeBolcks下wxSmith的C++编程教程——使用菜单和组件
  • 单调队列
  • 软工第一次编程
  • 第二次软工作业
  • 9.23总结
  • 日志|力扣|不同路径|最小路径和|动态规划|Javase|IO|File|Javaweb
  • 如何建立 5 μm 精度的视觉检测?不仅仅是相机的事
  • 函数 cmd_info_change_cur_model_group
  • 线程--相关概念、两种创建线程的方式
  • 恢复某个数据文件不适当,导致DataGuard无法open数据库
  • Nginx 部署及配置
  • vite静态资源处理
  • 洛谷B4040 [GESP202409 四级] 黑白方块 题解
  • SerpApi:一站式搜索引擎数据抓取API完全指南
  • 补whk时的鲜花(持续更新)
  • css 使用记录 随笔
  • newDay02
  • 【OI 档案-2025】CSP 赛前集训记(初赛后+复赛)
  • Git 从零到一:以 Gitee 为例的实战与可视化指南
  • 代码随想录算法训练营第七天 |第454题.四数相加II、383. 赎金信、第15题. 三数之和
  • day06
  • 前沿速览:TrafficVLM、DeepSeek-Terminus、Qwen3-Omni、蚂蚁百灵、Wan2.2-Animate、Qianfan-VL
  • 代码随想录算法训练营第七天 | leetcode 454 383 15 18
  • 概率期望
  • Day2
  • 2025.9.23总结 - A
  • 8
  • 从3亿到48亿:NuGet周下载量跃迁背后的.NET生态演进与未来挑战(2019-2025)