【问题标题】:SqlException: On Delete Cascade not working ASP.NETSqlException:在删除级联不工作 ASP.NET
【发布时间】:2021-04-30 20:14:45
【问题描述】:

当我尝试从 ASP.NETUsers 表中删除用户时,我得到 SqlException:

SqlException:DELETE 语句与 REFERENCE 冲突 约束“FK_Applications_AspNetUsers_UserID”。发生了冲突 在数据库“JobGuide”、表“dbo.Applications”、“UserID”列中。

出现此问题是因为用户 ID 是另一个表中的外键,但“在删除级联时”不起作用。有关更多详细信息,这是我的模型:

我的扩展身份用户:

public class AppUser : IdentityUser
{
    public string Name { get; set; }
    public string City { get; set; }
    public string RoleName { get; set; }

    public virtual ICollection<Application> Applications { get; set; }
}

应用模型(即当用户申请工作时):

public class Application
{
    public int ApplicationID { get; set; }

    public int JobID { get; set; }
    public virtual Job Job { get; set; }
    
    public string UserID { get; set; }
    public virtual AppUser User { get; set; }
}

工作模式:

public class Job
{
    public int JobID { get; set; }
    public string Title { get; set; }

    public virtual ICollection<Application> Applications { get; set; }
}

到目前为止,我创建了两个一对多关系,AspNetUser 与 Application 一对多,Job 与 Application 一对多。

这是我的 Fluent API 映射配置:

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);

    builder.Entity<Application>()
        .HasKey(i => i.ApplicationID);

    builder.Entity<Application>()
           .HasOne<AppUser>(sc => sc.User)
           .WithMany(s => s.Applications)
           .HasForeignKey(sc => sc.UserID)
           .OnDelete(DeleteBehavior.Cascade);

    builder.Entity<Application>()
           .HasOne<Job>(sc => sc.Job)
           .WithMany(s => s.Applications)
           .HasForeignKey(sc => sc.JobID)
           .OnDelete(DeleteBehavior.Cascade);
}

从控制器中删除方法:

    var userInfo = await userManager.FindByIdAsync(user.Id);
    if (userInfo == null) 
    {
        return NotFound();
    }
    _ = await userManager.RemoveFromRoleAsync(userInfo, userInfo.RoleName);
    _ = await userManager.DeleteAsync(userInfo);
    
    int rowsAffected = await db.SaveChangesAsync();

知道为什么这个错误没有消失,Fluent API 好吗?或者我需要输入原始 Sql 来删除该用户的应用程序,然后再删除用户?我查看了几乎所有类似的问题,但没有一个对我有用。

【问题讨论】:

  • 根据模型和Fluent API配置,我创建了一个Asp.net core 3.1 MVC应用程序,当我使用你的删除代码删除用户时,它会显示CS1503错误,更改后到userManager.DeleteAsync(userInfo.result),CS1503错误消失,相关数据删除成功,检查this screenshot。请检查迁移文件,配置级联删除后是否启用迁移。并检查数据库是否有空值。此外,您可以尝试从 DbContext 中删除级联项。
  • 我已经测试了我的删除代码,它工作正常,但只有当用户在 Applications 表中没有应用程序时,当用户有应用程序时,才会出现异常。我试过你的代码,但仍然失败。我检查了数据库,在 Applications 表 -> 键 ->“FK_Applications_AspNetUsers_UserID”中删除规则是“No action”,我将其更改为“Cascade”,但仍然失败。我尝试了另一种使用原始 SQL 命令的方法,请查看此屏幕截图link,此方法运行良好,但在我看来,它不是删除用户的适当方法?
  • 您好@sycamore55,好像应用表中没有配置级联删除,尝试使用SSMS检查:打开SQL Server Object Explorer(或使用Server Explorer),找到SQL Server Database,然后右击 Applications table -> Script As -> CREATE To -> New Query Window,然后查看该表是否配置了级联删除,查看this screenshot
  • @ZhiLv 哦,你救了我的命哈哈,我发誓我检查过了,但显然我没有保存,将此评论发布为答案,我将标记为已解决,谢谢。
  • 嗨@sycamore55,很高兴听到它确实有助于解决问题。我将其添加为答案,希望它可以帮助其他社区成员快速解决类似问题。祝你有美好的一天!

标签: asp.net sql-server asp.net-mvc asp.net-core entity-framework-core


【解决方案1】:

你能换个方式试试吗?

builder.Entity<User>()
    .HasMany<Application>(u => u.Applications)
    .WillCascadeOnDelete();

或在您的代码中使用.WillCascadeOnDelete()

【讨论】:

  • 我试过了,但它不起作用,说:"NavigationBuilderCollection 不包含'Willcascadeondelete'的定义 :/
  • @sycamore55 哦,你用的是实体框架核心?
  • 是的,我忘了提。
【解决方案2】:

好像应用表中没有配置级联删除,尝试使用SSMS查看:

打开SQL Server Object Explorer(或使用Server Explorer),找到SQL Server Database,然后右击Applications表 -> Script As -> CREATE To -> 新建查询窗口,然后查看表是否配置了级联删除,查看这个截图:

为解决此问题,请在使用 Fluent API 映射配置 Cascade Delete 后,请记得启用迁移并更新数据库:

  Add-Migration AddCascadeDelete
  Update-Database

此外,您还可以通过执行以下 SQL 命令(通过 SSMS)来配置级联删除:

ALTER TABLE [dbo].[Applications]
    ADD CONSTRAINT [FK_Applications_AspNetUsers_UserID] FOREIGN KEY ([UserID]) REFERENCES [dbo].[AspNetUsers] ([Id]) ON DELETE CASCADE;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-30
    • 2013-06-22
    • 2013-03-03
    • 1970-01-01
    • 1970-01-01
    • 2012-11-18
    相关资源
    最近更新 更多