0

在 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)

有人有这个问题吗?

4

1 回答 1

0

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 中所示:

[...]

本质上,有两个步骤:

  1. 您需要派生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 
}
  1. 您需要提供模式名称转换器:
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();
于 2021-10-28T13:49:33.203 回答