entity-framework-core - 更新到 .NET 5 DataAnnotations.Schema 不再起作用。LINQ 连接多个数据库/查询失败
问题描述
在 Core 3.0 中,我可以加入多个数据库/模式。这是 dbEarth 中的 Order 类:
namespace dgNet.Core.Models.Earth
{
[Table("tbl_Order", Schema ="Earth")]
public class Order : EntityBaseWithTypedId<int>
{
[Key]
[Column("BestID")]
public override int Id { get; set; }
这是 dbMars 中的类 SerialNumber
namespace dgNet.Core.Models.Mars
{
[Table("tbl_serialnumber", Schema = "Mars")]
public class SerialNumber : EntityBaseWithTypedId<int>
{
[Column("serialnumber")]
public int Serialnumber { get; set; }
[Column("jobId")]
public int JobId { get; set; }
[ForeignKey("JobId")]
public Order Order { get; set; }
数据注释相当于这里的代码:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Order>().ToTable("tbl_Order", "Earth");
}
因此,如果构建一个 LINQ 查询并将 Order(dbEarth) 包含在 SerialNumber(dbMars) 中,它运行良好。
query => query.Include(serialNumber => serialNumber.Order).FirstOrDefault();
更新到 Core 5.0 SQL 后,查询创建不正确。
SQL 将 Orders 连接到与 SerialNumbers 相同的数据库/模式上。
使用最新的 NuGet 包 .AspCore (5.0.10) DB = MySQL 使用 Pomelo.EntityFrameworkCore.MySql (5.0.2)
有人有这个问题吗?
解决方案
MySQL 不支持架构的 EF Core 概念。
架构的 EF Core 概念与 SQL Server 使用的架构概念相同,其中架构基本上只是类别(组织单位),您可以使用它们将多个表在同一数据库中逻辑地组合在一起。
MySQL 所称的 schemas 实际上是数据库,在 EF Core 中单个DbContext
不支持多个数据库。
因此,我们在 Pomelo 3.2.0 中正式移除了非常脆弱的多数据库支持。
如果已为对象 #982 设置了模式,则处理此问题的官方方法显示在实现当前行为的替代方案以始终抛出:
目前有3个选项可供选择:
// Throw an exception, if a schema is being used. This is the default. options.UseMySql(myConnectionString, b => b.SchemaBehavior(MySqlSchemaBehavior.Throw)) // Silently ignore any schema definitions. options.UseMySql(myConnectionString, b => b.SchemaBehavior(MySqlSchemaBehavior.Ignore)) // Use the specified translator delegate to translate from an input schema and object name to // an output object name whenever a schema is being used. options.UseMySql(myConnectionString, b => b.SchemaBehavior(MySqlSchemaBehavior.Translate, (schema, entity) => $"{schema ?? "dbo"}_{entity}"))
还有一种方法可以显式启用旧行为,如 ModelBuilder.HasDefaultSchema is not working (No database selected) #22971 (comment) for Pomelo 3.2.x 中所示:
[...]
本质上,有两个步骤:
- 您需要派生
MySqlSqlGenerationHelper
并覆盖GetSchemaName
:public class CustomMySqlSqlGenerationHelper : MySqlSqlGenerationHelper { public CustomMySqlSqlGenerationHelper( RelationalSqlGenerationHelperDependencies dependencies, IMySqlOptions options) : base(dependencies, options) { } protected override string GetSchemaName(string name, string schema) => schema; // <-- this is the first part that is needed to map schemas to databases }
- 您需要提供模式名称转换器:
optionsBuilder .UseInternalServiceProvider(serviceProvider) // use our ServiceProvider .UseMySql( "server=127.0.0.1;port=3308;user=root;password=;database=EFCoreIssue22971_01_IceCreamParlor", b => b.ServerVersion("8.0.21-mysql") .SchemaBehavior( MySqlSchemaBehavior.Translate, (schemaName, objectName) => objectName) // <-- this is the second part that is needed to map // schemas to databases .CharSetBehavior(CharSetBehavior.NeverAppend)) .EnableSensitiveDataLogging() .EnableDetailedErrors();
推荐阅读
- bash - 使用单个 ImageMagick 命令更改目录及其子目录中的所有图像?
- asp.net-mvc - 剑道网格不显示任何数据
- java - 通过 jar 运行的应用程序无法连接到 MySQL NoSuchAlgorithmException: SHA-256 MessageDigest
- flutter - Flutter:弹出表单值显示为空
- wordpress - /page/2, /page/3, 页面重定向到主页 permanlink 错误 wordpress
- windows - 比较 2 个文件之间的列并使用 Powershell 删除非常用列
- node.js - 如何为 ng build 命令选择节点版本?
- c++ - 发布的结果与调试的结果不同
- mongodb - 如何允许分配不兼容的 Typescript 类型?
- c++ - 我的值在我的设置函数中没有改变