如何删除具有外键约束的记录?

12

我开始了一个新的ASP.NET MVC 3应用程序,并��到以下错误:

由于仍存在对该键的引用,因此无法删除主键值。

如何解决这个问题?

模型(EF代码优先)

public class Journal
{
    public int JournalId { get; set; }
    public string Name { get; set; }
    public virtual List<JournalEntry> JournalEntries { get; set; }
}
public class JournalEntry
{
    public int JournalEntryId { get; set; }
    public int JournalId { get; set; }
    public string Text { get; set; }
}

控制器

//
// POST: /Journal/Delete/5

[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id)
{            
    Journal journal = db.Journals.Find(id);
    db.Journals.Remove(journal);
    db.SaveChanges(); // **exception occurs here**
    return RedirectToAction("Index");
}

数据库设置

public class FoodJournalEntities : DbContext
{
    public DbSet<Journal> Journals { get; set; }
    public DbSet<JournalEntry> JournalEntries { get; set; }
}

1
在数据库中,您可以为父表选择级联删除选项吗? - Pankaj
你的答案可能已经在这里(https://dev59.com/GG035IYBdhLWcg3wQt2n#5522422)了。如果没有,发布DbSetup代码。你可以删除View。 - H H
@PankajGarg - 我已经验证了数据库已经设置了这个。 - O.O
@HenkHolterman - 好的,我已经发布了。 - O.O
4个回答

23

找到解决方案:

public class FoodJournalEntities : DbContext
{
    public DbSet<Journal> Journals { get; set; }
    public DbSet<JournalEntry> JournalEntries { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Journal>()
               .HasOptional(j => j.JournalEntries)
               .WithMany()
               .WillCascadeOnDelete(true);
        base.OnModelCreating(modelBuilder);
    }
}

来源


11
如果您从一个表(比如“blah”)中删除一条记录,而该表与其他表(xyz、abc)存在关系。默认情况下,如果其他表中存在相关行,则数据库将阻止您删除“blah”中的行。
解决方案 #1:
您可以手动先删除相关行,这可能需要大量工作。
解决方案 #2:
一个简单的解决方案是配置数据库,在删除“blah”行时自动删除它们。

按照以下步骤打开数据库图表,然后点击关系属性。

enter image description here

在属性窗口中,展开INSERTUPDATE规范,并将DeleteRule属性设置为级联。
enter image description here 保存并关闭图表。如果询问是否要更新数据库,请单击“是”。
为了确保模型使内存中的实体与数据库同步,您必须在数据模型中设置相应的规则。打开SchoolModel.edmx,右键单击“blah”和“xyz”之间的关联线,然后选择属性。
在属性窗口中,展开INSERTUPDATE规范,并将DeleteRule属性设置为级联。

解决方案和图片取自http://www.asp.net/web-forms/tutorials/getting-started-with-ef/the-entity-framework-and-aspnet-getting-started-part-2


这个解决方案似乎适用于 EF 4.1 之前的版本。数据库已经设置好了。 - O.O

4
在 EF Core (3.1.8) 中,语法与被接受的答案略有不同,但是相同的一般思路,对我有效的内容如下:
modelBuilder.Entity<Journal>()
            .HasMany(b => b.JournalEntries)
            .WithOne()
            .OnDelete(DeleteBehavior.Cascade);

在从数据库中选择要删除或移除的项目的查询中,您需要确保明确包含这些项目,否则它将继续抛出FK错误,类似于下面的内容。

var item = _dbContext.Journal.Include(x => x.JournalEntries).SingleOrDefault(x => x.Id == id);

-2

我发现了...

进入SQL Server

将他的数据库制作成图表

右键点击父子关系线并打开其属性。

设置插入和更新规范,然后将删除规则简单地设置为级联。

记住,在项目中不需要编写代码来实现此目的,只需调试并享受它。


这是与Owais Qureshi发布的解决方案相同,但质量较低的解决方案。 - Jan

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