Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I delete related objects in Entity framework code first database?

DBContext class is

public class VGDB : DbContext
    {        
        public DbSet<Planet> Planets { get; set; }
    }

And model looks like:

public class Planet
    {
        [Key]
        public int Id { get; set; }
        public string Name { get; set; }

        ...

        public List<Building> Constructions { get; set; } 
    }


public class Building
    {
        [Key]
        public int Id { get; set; }
        public decimal Lvl { get; set; }
        public string Type { get; set; }
    }

Repository class:

public class VGDBRepository
    {
        private readonly VGDB _vgdb;
        ...
        public void RemovePlanets()
        {
            foreach (Planet planet in _vgdb.Planets)
            {
                _vgdb.Planets.Remove(planet);
            }
            _vgdb.SaveChanges();
        }
        ...
    }

Entity Framework creates database with two tables: Planets and Buildings, related by Planet_Id field. When I call RemovePlanets() method of my VGDBRepository class it removes planets record from Planets table and sets Planet_Id field of all buildings, related with deleted planets, in Buildings table to null but not deletes them, so I have redundant records in database. I use code-first strategy to create database. How can I force Entity Framework to remove such type of related data???

like image 777
Dmytro Avatar asked Jan 16 '23 00:01

Dmytro


2 Answers

You would need to cascade your deletes.

Take a look at this: Stackoverflow Example Cascade Deletes

And this: Msdn Code First with Enabling Cascade Deletes

like image 136
MikeTWebb Avatar answered Jan 24 '23 05:01

MikeTWebb


I had the exact same problem and I recently figured out how to fix it so I thought I'd just add on to the answer provided by Dima.

The code that you have above for Planet and Building look very similar to how I had my related objects set up; it made sense to me to set up the relations like that. Moreover, the tables seemed to generate correctly with a FK reference back to the parent table. Like you, when I deleted my parent record (Planets, in your case), the child records (Buildings, in your case) still stuck around but the FK field had the parent ID removed so that it just had a null value. The objects were removed from the in memory collection, though, so things were getting out of sync. The thing that was really confusing to me was that Entity Framework Code First is supposed to, by default, cascade deletes like this and I didn't understand why my deletes weren't cascading.

After some digging around, I found that I had to set up a Foreign Key Association within the child class so that Entity Framework did the cascade delete correctly. So you would need to change your code to look like this:

    public class Planet
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }

    ...

    public List<Building> Constructions { get; set; } 
}


public class Building
{
    [Key]
    public int Id { get; set; }
    public decimal Lvl { get; set; }
    public string Type { get; set; }
    //Add these two properties to create the Foreign Key Association
    public int planetID { get; set; }
    public Planet planet { get; set; }
}

As soon as I added the two properties and did an automigration on my database, the deletes cascaded just like I expected them to. I'm still a little unclear on why this needs to be done, but that's a subject for a separate post... I just thought that I'd share what had gotten this working for me.

like image 32
greyseal96 Avatar answered Jan 24 '23 05:01

greyseal96