.NET Core 2 EF在将外键列更改为可空时出现问题

7

我正在开发一个使用 .Net Core 2、EF Core 和 MySQL 数据库服务器的应用程序,采用 Code First 方法。

我有两个表:

  1. User(用户)
  2. Employee(员工)

User 表是主表,包含用户信息,Employee 表是子表,具有 ID_User 列,如下所示:

 public class User : BaseEntity
    {
        public int ID_User { get; set; }
        public string Name { get; set; }
        public string UserName { get; set; }
        public string Password { get; set; }

        public virtual ICollection<Employee> Employees{get;set;}
    }



 public class Employee : Entity
    {
        public int ID_Employee { get; set; }
        public string Name { get; set; }

        public int ID_User { get; set; }

        public virtual User User { get; set; }
    }

当我使用上述映射并且两个表中都有足够的数据时,一切都运作得很完美。
现在,我希望将Employee表中的ID_User列设置为可为空。
为了实施此更改,我对我的模型进行了以下更改:
public class Employee : Entity
    {
        public int ID_Employee { get; set; }
        public string Name { get; set; }

        public int? ID_User { get; set; }

        public virtual User User { get; set; }
    }

在映射文件中:

builder.HasOne(x=>x.User).WithMany(y=>y.Employees).HasForeignKey(z=>z.ID_User).IsRequired(false);

运行dotnet ef migrations add empuser命令后,它生成了以下迁移代码:
  migrationBuilder.DropForeignKey(
            name: "FK_Employee_User_ID_User",
            table: "Employee");

        migrationBuilder.AlterColumn<int>(
            name: "ID_User",
            table: "Employee",
            nullable: true,
            oldClrType: typeof(int));

        migrationBuilder.AddForeignKey(
            name: "FK_Employee_User_ID_User",
            table: "Employee",
            column: "ID_User",
            principalTable: "User",
            principalColumn: "ID_User",
            onDelete: ReferentialAction.Restrict);

现在当我运行 dotnet ef database update 命令时,它会给我以下错误信息:

您的 SQL 语法存在错误;请检查与您的 MySQL 服务器版本相对应的手册,以获取使用正确语法的方法。 错误出现在 'CONSTRAINT FK_Employee_User_ID_User' 行附近,位于第一行。

请帮忙解决。
谢谢。

你可以尝试使用其他提供者,比如内存,这样你就可以将问题缩小到提供者或MySQL。 - Neville Nazerane
2
@NevilleNazerane 实际上,该项目非常庞大,采用多层方法和遵循存储库/UOW模式。如果我进行此更改,我将不得不在许多地方进行修改,这需要很长时间。如果我们有其他选择,那就太好了。根据错误消息,问题明显来自于MySql,因为在使用SQL服务器时,相同的代码是有效的。 - Harsh Sharma
我最近几周一直在重度使用EF Core 2和MySql。我一直在使用Pomelo提供程序。当我不得不删除主键时,就像你在这里做的那样,通常会失败。由于我仍然处于绿地开发阶段(产品尚未推出),所以我只需清除迁移并重新开始。这肯定不是一个答案,但如果在您的情况下有效,那么值得一试。 - Collin Barrett
值得一试的是,尝试移除 Employee.User 上的 virtual 关键字。 如果有帮助的话,我在这里的项目中正在为 LicenseIdSyntaxId 进行类似的设置:https://github.com/collinbarrett/FilterLists/blob/master/src/FilterLists.Data/Entities/FilterList.cs - Collin Barrett
3
我之前使用的是官方的MySQL连接器,导致了这个问题。后来我转用Pomelo连接器,现在一切正常了。感谢大家的建议。 - Harsh Sharma
显示剩余2条评论
3个回答

5
尝试将SQL语句直接放入MySQL Workbench中。
1. 在命令提示符中输入“dotnet ef migrations script”。 2. 复制生成的SQL脚本。 3. 将其粘贴到您的Workbench中。 4. 检查错误发生的位置。
当我使用EF Core 2与MySQL时遇到类似的错误,这帮助我更好地理解问题并解决了问题(对我来说是一个打字错误)。您至少可以使用此方法确定是否存在迁移或SQL语句中的错误。
我知道这不是一个具体的解决方案,但我希望这能帮助您理解您的问题并解决它 :)

1
对于那些使用程序包管理器控制台的用户:Script-Migration -From firstMigration -To secondMigration - Ziad Akiki

0

0

在某些版本的MYSQL中,不支持关键字CONSTRAINT。EF Core生成删除外键的drop constraint。我必须更改以下内容:

migrationBuilder.DropForeignKey(
            name: "FK_XXXXX",
            table: "XXXXXX");

migrationBuilder.Sql("ALTER TABLE XXXXXX DROP FOREIGN KEY FK_XXXXX");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接