.NET Core 3迁移至.NET 9时EF Core MySQL多Schema识别异常问题求助
嘿,这个问题我之前帮朋友排查过类似的,从.NET 3跳升到.NET 9,EF Core和MySQL驱动的一些默认行为确实有不少变化,咱们一步步来定位解决:
先确认MySQL EF Core驱动版本是否匹配
.NET 9对应的EF Core版本是9.x系列,你必须使用和.NET版本完全兼容的Pomelo MySQL驱动(目前主流的MySQL EF Core驱动就是Pomelo的)。旧版本的驱动(比如适配EF Core 3.x的)根本没法在.NET 9下正常工作,大概率会出现映射异常这类问题。
你可以通过NuGet包管理器卸载旧驱动,安装对应版本的稳定版:
如果用Package Manager Console:
Uninstall-Package Pomelo.EntityFrameworkCore.MySql Install-Package Pomelo.EntityFrameworkCore.MySql -Version 9.0.0
如果用dotnet CLI命令:
dotnet remove package Pomelo.EntityFrameworkCore.MySql dotnet add package Pomelo.EntityFrameworkCore.MySql --version 9.0.0
统一Schema配置方式,避免冲突
EF Core 6+之后,数据注解和Fluent API的优先级处理有细微调整,建议你统一用一种配置方式,避免两边配置不一致导致的覆盖问题:
方式一:全用Fluent API配置
确保在OnModelCreating里的配置清晰无冲突:
protected override void OnModelCreating(ModelBuilder modelBuilder) { // 全局设置默认Schema modelBuilder.HasDefaultSchema("myschema"); // 配置实体表,这里因为已经设了默认Schema,后面的Schema参数可以省略,也可以明确写上去确保万无一失 modelBuilder.Entity<MyClassTable>().ToTable("myclasstable", "myschema"); }
方式二:全用数据注解配置
把Fluent API里的ToTable配置去掉,只保留实体上的[Table]属性:
[Table("myclasstable", Schema = "myschema")] public class MyClassTable { [Key] public int Id { get; set; } public string Description { get; set; } }
注意:EF Core中Fluent API的配置优先级高于数据注解,如果两边都写了不同的Schema,会以Fluent的配置为准,这很容易踩坑!
检查连接字符串的默认Database设置
有些时候,连接字符串里的Database参数会被MySQL驱动当作默认Schema来使用,尤其是在.NET 9的驱动版本中,这个逻辑可能和旧版本不同。比如如果你的连接字符串写的是Server=xxx;Database=default_schema;Uid=xxx;Pwd=xxx;,而你的实际表在myschema下,驱动可能会默认用default_schema来生成SQL,导致表不存在的错误。
你可以确认连接字符串里的Database是否是你要操作的数据库实例,同时确保你的myschema在这个数据库下是存在的(或者如果是MySQL的多Database场景,要把连接字符串的Database改成myschema,具体根据你的实际数据库结构调整)。
排查EF Core生成的SQL语句
你可以开启EF Core的详细日志,仔细看生成的SQL里用的Schema是哪个,然后反向排查这个Schema的来源:
- 是不是连接字符串里的
Database值? - 是不是EF Core的默认Schema被某个地方覆盖了?比如在
AddDbContext的时候有没有额外配置?
另外,你可以临时写一个原生SQL查询测试:
var data = await _context.MyClassTable.FromSqlRaw("SELECT * FROM myschema.myclasstable").ToListAsync();
如果这个查询能正常返回数据,说明是EF Core的实体映射有问题;如果还是报错,那就要检查数据库本身的权限、Schema/表是否真的存在了。
内容来源于stack exchange

