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



我试图从数据库中删除User,User有自己的Recipes。级联删除不工作,即使我配置它在模型生成器。

得到的错误是:

SqlException: The DELETE statement conflicted with The REFERENCE constraint "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跟踪的相关实体,而如果EF被设置为管理模式,Cascade也将在数据库中设置FK约束上的delete孤儿。

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

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

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

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

我设法通过改变这一行来解决这个问题:var user = _applicationDbContext.Users。在哪里(u =比;uid == appuser.Id).FirstOrDefault();var user = _userManager.Users.Include(e=>e. recipes)。在哪里(u =比;u.Id == appuser.Id).FirstOrDefault();

最新更新