【问题标题】:SqlException: The DELETE statement conflicted with the REFERENCE constraint, can't seem to get cascade delete to workSqlException:DELETE 语句与 REFERENCE 约束冲突,似乎无法让级联删除工作
【发布时间】:2021-04-24 22:37:45
【问题描述】:

我收到此错误:

SqlException:DELETE 语句与 REFERENCE 约束“FK_Games_AspNetUsers_VideoGamesUserId”冲突。冲突发生在数据库“VideoGames”、表“dbo.Games”、列“VideoGamesUserId”中。 声明已终止。

尝试从我的数据库中删除 VideoGamesUser 的实例时。

  public class VideoGamesUser : IdentityUser
{
    public List<Game> UserGameLibrary { get; set; }

    public VideoGamesUser(List<Game> games)
    {
        UserGameLibrary = games;
    }

    public VideoGamesUser()
    {

    }
}

这里还有 Game 类

 public class Game
{
    public long GameId { get; set; }
    [Required]
    public string Name { get; set; }
    public string Genre { get; set; }
    public bool Completed { get; set; }
    public VideoGamesUser VideoGamesUser { get; set; }
    

    public Game(string name, string genre, bool completed, int id)
    {
        GameId = id;
        Name = name;
        Genre = genre;
        Completed = completed;

    }

    public Game()
    {
       

    }

}

我已经搜索了相关问题,我认为问题是因为游戏桌

CREATE TABLE [dbo].[Games] (
[GameId]           BIGINT         IDENTITY (1, 1) NOT NULL,
[Name]             NVARCHAR (MAX) NOT NULL,
[Genre]            NVARCHAR (MAX) NULL,
[Completed]        BIT            NOT NULL,
[VideoGamesUserId] NVARCHAR (450) NULL,
CONSTRAINT [PK_Games] PRIMARY KEY CLUSTERED ([GameId] ASC),
CONSTRAINT [FK_Games_AspNetUsers_VideoGamesUserId] FOREIGN KEY ([VideoGamesUserId]) REFERENCES [dbo].[AspNetUsers] ([Id])

通过外键引用 VideoGamesUser 类,因此如果不先删除 Games 表的内容,我无法删除 VideoGamesUser。但据我了解,级联删除应该能让我同时删除两者。

所以我的问题是即使遵循这个

https://www.tektutorialshub.com/entity-framework-core/cascade-delete-in-entity-framework-core/

我的 dbcontext 类生成的 OnModelCreating 方法:

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

        builder.Entity<Game>()
            .HasOne<VideoGamesUser>(u => u.VideoGamesUser)
            .WithMany(g => g.UserGameLibrary)
            .HasForeignKey("VideoGamesUserId")
            .IsRequired(true)
            .OnDelete(DeleteBehavior.Cascade);

    }
}

我仍然收到错误消息。我想我只是不明白这里的东西。任何想法或方向将不胜感激。谢谢。

编辑:

delete 方法是我在 ASP.Net Identity 中搭建脚手架时提供的内置方法

 public async Task<IActionResult> OnPostAsync()
    {
        var user = await _userManager.GetUserAsync(User);
        if (user == null)
        {
            return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
        }

        RequirePassword = await _userManager.HasPasswordAsync(user);
        if (RequirePassword)
        {
            if (!await _userManager.CheckPasswordAsync(user, Input.Password))
            {
                ModelState.AddModelError(string.Empty, "Incorrect password.");
                return Page();
            }
        }
      
        var result = await _userManager.DeleteAsync(user);
        var userId = await _userManager.GetUserIdAsync(user);
        if (!result.Succeeded)
        {
            throw new InvalidOperationException($"Unexpected error occurred deleting user with ID '{userId}'.");
        }

        await _signInManager.SignOutAsync();

        _logger.LogInformation("User with ID '{UserId}' deleted themselves.", userId);

        return Redirect("~/");
    }

【问题讨论】:

  • 请显示您的删除操作
  • 已添加,对此感到抱歉。
  • 在修改 fluent 配置后,您似乎没有生成和/或应用新的迁移到数据库。
  • 我创建了一个新的迁移并应用了它。如果有帮助,我可以添加快照的游戏桌部分

标签: c# entity-framework asp.net-core .net-core entity-framework-core


【解决方案1】:

你可以试试

    .OnDelete(DeleteBehavior.ClientSetNull)

但它也不可靠。控制一切总是更好的:

修复你的游戏类

public class Game
{
    [Key]
    public long GameId { get; set; }

    [Required]
    public string Name { get; set; }

    public string Genre { get; set; }
    public bool Completed { get; set; }
     public int VideoGamesUserId { get; set; }

    [ForeignKey(nameof(VideoGamesUserId ))]
    [InverseProperty("UserGameLibrary")]
    public VideoGamesUser VideoGamesUser { get; set; }

     .......

}


  public class VideoGamesUser : IdentityUser
{
   
    [InverseProperty(nameof(Game.VideoGamesUser ))]
    public List<Game> UserGameLibrary { get; set; }
    
    .......

}

还有行动

....


 

 var videoGames =  await _context.Games.Where(i=> i.VideoGamesUserId == user.Id ) 
.ToListAsync();

if(videoGames!=null)  
{
  foreach(var game in videoGames)
  {
   game.VideoGamesUserId=null);
    _context.Entry(game).State = EntityState.Modified;
  }
   await _context.SaveChangesAsync();
}

var userId = await _userManager.GetUserIdAsync(user);

  var result = await _userManager.DeleteAsync(user);

.....

【讨论】:

  • 仅供参考 ToListAsync 在等待时不会返回 null
  • 我无法引用 VideoGamesUserId,因为它是由 EF 自动生成的,不是我的游戏模型的一部分。我是否应该自己添加该属性并阻止 EF 以某种方式生成它?
  • @Frawsty 只需将 VideoGamesUserId 添加到您的 Came 类。
  • 非常感谢您让它工作。我非常感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多