简体   繁体   English

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

[英]How to delete a record with a foreign key constraint?

Started a new ASP.NET MVC 3 application and getting the following error:启动一个新的 ASP.NET MVC 3 应用程序并收到以下错误:

The primary key value cannot be deleted because references to this key still exist.无法删除主键值,因为对该键的引用仍然存在。

How to solve this?如何解决这个问题?

Models (EF code-first)模型(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; }
}

Controller控制器

//
// 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");
}

DB Setup数据库设置

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

Found the solution:找到了解决办法:

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);
    }
}

Source 来源

If you delete a record from a table(lets say "blah"), which has other relationships with other tables (xyz,abc).如果您从表中删除一条记录(可以说“等等”),它与其他表(xyz,abc)有其他关系。 By default, the database will prevent you from deleting a row in "blah" if there are related rows in one of the other tables.默认情况下,如果其他表之一中有相关行,数据库将阻止您删除“blah”中的行。
Solution #1:解决方案#1:
You can manually delete the related rows first,this may require a lot of work.您可以先手动删除相关行,这可能需要大量工作。
Solution #2:解决方案#2:
an easy solution is to configure the database to delete them automatically when you delete a "blah" row.一个简单的解决方案是将数据库配置为在删除“blah”行时自动删除它们。

Follow this open your Database diagram,and click on the properties on the relationship按照这个打开你的数据库图,然后点击关系上的属性

在此处输入图片说明

In the Properties window, expand INSERT and UPDATE Specification and set the DeleteRule property to Cascade.在 Properties 窗口中,展开INSERTUPDATE Specification 并将DeleteRule属性设置为 Cascade。
在此处输入图片说明

Save and close the diagram.保存并关闭图表。 If you're asked whether you want to update the database, click Yes.如果系统询问您是否要更新数据库,请单击是。

To make sure that the model keeps entities that are in memory in sync with what the database is doing, you must set corresponding rules in the data model.为了确保模型使内存中的实体与数据库正在执行的操作保持同步,您必须在数据模型中设置相应的规则。 Open SchoolModel.edmx, right-click the association line between "blah" and "xyz", and then select Properties.打开 SchoolModel.edmx,右键单击“blah”和“xyz”之间的关联线,然后选择“属性”。

In the Properties window, expand INSERT and UPDATE Specification and set the DeleteRule property to Cascade.在 Properties 窗口中,展开INSERTUPDATE Specification 并将DeleteRule属性设置为 Cascade。

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

In EF Core (3.1.8), the syntax is a bit different than the accepted answer but the same general idea, what worked for me is below:在 EF Core (3.1.8) 中,语法与接受的答案略有不同,但总体思路相同,对我有用的内容如下:

modelBuilder.Entity<Journal>()
            .HasMany(b => b.JournalEntries)
            .WithOne()
            .OnDelete(DeleteBehavior.Cascade);

In your query to select the item to delete or remove from the database you want to make sure that you are explicitly including the items as well, otherwise it will continue to throw a FK error, something like below.在您选择要从数据库中删除或删除的项目的查询中,您要确保明确包含这些项目,否则它将继续抛出 FK 错误,如下所示。

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

I found it...我找到了...

Go TO SQL Server转到 SQL Server

Make his Database diagrammed使他的数据库图表化

Right click on relation ship line between parent and child and open the property of it.右击父子关系线,打开它的属性。

Set INSERT And Update Specification and simply set DELETE RULE TO CASCADE.设置 INSERT And Update Specification 并简单地设置 DELETE RULE TO CASCADE。

Remember No code is required in Project FOR this PURPOSE and simply debug and enjoy it.请记住,为此目的在项目中不需要任何代码,只需调试并享受它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM