微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

级联删除在 Asp.net 5 和 EF Core 中不起作用

如何解决级联删除在 Asp.net 5 和 EF Core 中不起作用

我正在尝试从数据库删除 UserUser 有它自己的 Recipes。即使我在模型构建器中配置了级联删除,它也不起作用。

我得到的错误是:

sqlException:DELETE 语句与 REFERENCE 约束“FK_Recipes_AspNetUsers_ApplicationUserId”冲突。数据库“master”、表“dbo.Recipes”、“ApplicationUserId”列发生冲突。

AplicationUser.cs

namespace WebApplication.Models
{
    public class ApplicationUser : IdentityUser
    {
        public ICollection<Recipe> Recipes { get; set; }
    }
}

Recipe.cs

namespace WebApplication.Models
{
    public class Recipe
    {
        [Key]
        public Guid Id { get; set; }
        [required]
        public string RecipeName { get; set; }
        [required]
        public string RecipeContent { get; set; }
        public string ApplicationUserId { get; set; }
        public ApplicationUser ApplicationUser { get; set; }
    }
}

ApplicationDbContext.cs

namespace WebApplication.Models
{
    public class ApplicationDbContext : IdentityDbContext
    {
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<ApplicationUser>().HasMany(e => e.Recipes).WithOne(e => e.ApplicationUser)
                .OnDelete(DeleteBehavior.ClientCascade);


        }

        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
        {
        }

        public DbSet<Recipe> Recipes { get; set; }
        public DbSet<ApplicationUser> ApplicationUsers { get; set; }
    }
}

UserController.cs

public IActionResult Delete(string id)
{
    var user = _applicationDbContext.Users
                                    .Where(u => u.Id == id).FirstOrDefault();
    return View(user);
}
      
[HttpPost]
public IActionResult Delete(ApplicationUser appuser)
{
    var user = _applicationDbContext.Users
                                    .Where(u => u.Id == appuser.Id).FirstOrDefault();
    _applicationDbContext.Users.Remove(user);
    _applicationDbContext.SaveChanges();

    return RedirectToAction("Index");
}

我一直在寻找解决方案大约一个小时,但没有任何效果

配置 modulbuilder 似乎对几乎所有人来说都是解决方案,但肯定对我不起作用。

解决方法

ClientCascade 只会删除由 DbContext 跟踪的相关实体,而 Cascade 还会在数据库中的 FK 约束上设置删除孤儿,如果设置了 EF 来管理模式。

您需要确保 hte DbContext 正在跟踪要删除的相关实体:

var user = _applicationDbContext.Users
    .Include(x => x.Recipies)
    .Where(u => u.Id == appuser.Id)
    .SingleOrDefault();

这可确保 DbContext 知道相关实体,并应在删除用户之前删除这些实体。您还需要注意可能引用用户记录或 FK 的任何其他实体。例如,如果其他记录正在跟踪类似 CreatedBy 的内容,那么这些记录可能会被设置为将 FK 返回给用户。依赖 ClientCascade 在这里可能会出现问题,级联删除可能不可取,而是选择软删除模型。 (即 ApplicationUser 上的 IsActive 标志而不是删除行)

此外,避免使用 First 方法,除非您需要多行并且特别想要第一行。这些方法也只能与 OrderBy 方法结合使用。如果您希望有 1 行,请使用 Single。如果您希望有 0 或 1 行,请使用 SingleOrDefault。这有助于确保任何意外的数据状态都会导致有意义的异常,而不是默默地做一些意外的事情。

,

我设法通过更改这一行来解决这个问题: var user = _applicationDbContext.Users.Where(u => u.Id == appuser.Id).FirstOrDefault(); 对此: var user = _userManager.Users.Include(e=>e.Recipes).Where(u => u.Id == appuser.Id).FirstOrDefault();

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。