I have these two models:
public partial class Country
{
public Country()
{
this.Dinners = new HashSet<Dinner>();
}
public int CountryID { get; set; }
public string Name { get; set; }
public virtual ICollection<Dinner> Dinners { get; set; }
}
and
public partial class Dinner
{
public Dinner()
{
this.TRsvps = new HashSet<TRsvp>();
}
public int DinnerID { get; set; }
public System.DateTime EventDate { get; set; }
public string Description { get; set; }
public string HostedBy { get; set; }
public Nullable<int> CountryID { get; set; }
public virtual Country Country { get; set; }
}
I got a bit confused on how Entity Framework will act when a user tries to delete a parent entity (in our case it is the Country
entity) that has child records (Dinners
).
For example if I have the following code inside my mvc action method:-
public ActionResult DeleteConfirmed(int id)
{
Country country = db.Countries.Find(id);
db.Countries.Remove(country);
db.SaveChanges();
return RedirectToAction("Index");
}
And exception will be raised if I try to remove a country which has dinners, which sounds valid.
I tried modifying my code as follow, by including the Dinners
when retrieving the Country
object:
Country country = db.Countries.Include(a => a.Dinners).Single(a2 => a2.CountryId = id);
db.Countries.Remove(country);
db.SaveChanges();
return RedirectToAction("Index");
No exception will be raised, so I thought that EF would have deleted the child dinners, but what happens is that it updates the countryID
FK inside the Dinners
table to be null.... (Cascade Set to Null
)
I tried looping over the Dinners
collection as follows:
public ActionResult DeleteConfirmed(int id)
{
Country country2 = db.Countries.Find(id) ;
foreach(var d in country2.Dinners)
{
db.Dinners.Remove(d);
}
db.Countries.Remove(country2);
db.SaveChanges();
return RedirectToAction("Index");
}
but this raised the following error:
An exception of type 'System.InvalidOperationException' occurred in System.Core.dll but was not handled in user code
Additional information: Collection was modified; enumeration operation may not execute.
I realized that I should explicitly call the .Tolist()
on the foreach to get the parent and all its children deleted as follows:
foreach(var d in country2.Dinners.ToList())
Can anyone advice if I getting things wrong, or this is the only way to support cascade on delete using EF ?
Thanks