简体   繁体   中英

How to delete a record with a foreign key constraint?

Started a new ASP.NET MVC 3 application and getting the following error:

The primary key value cannot be deleted because references to this key still exist.

How to solve this?

Models (EF code-first)

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). By default, the database will prevent you from deleting a row in "blah" if there are related rows in one of the other tables.
Solution #1:
You can manually delete the related rows first,this may require a lot of work.
Solution #2:
an easy solution is to configure the database to delete them automatically when you delete a "blah" row.

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.
在此处输入图片说明

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.

In the Properties window, expand INSERT and UPDATE Specification and set the DeleteRule property to 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

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:

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.

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

I found it...

Go TO 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.

Remember No code is required in Project FOR this PURPOSE and simply debug and enjoy it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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