I tried handle the cascading deletes manually deleting all of the related entities in the associated entity set
try
{
using (var context = new Model1())
{
var deleteEmp =
(from ed in context.EmployeeDept where ed.ID == edid select ed).FirstOrDefault();
foreach (EmployeeTask empTask in deleteEmp.EmployeeTasks)
{
context.EmployeeTasks.Remove(empTask);
}
context.EmployeeDepts.Remove(deleteEmp);
context.SaveChanges();
}
}
catch (Exception ex)
{
throw new Exception("Existing employee could not be deleted " + ex.ToString());
}
where edid is variable. When I debugging by click F10 all executed correct until the line: context.EmployeeTasks.Remove(empTask); is executed and cursor returns back to in . After that I got error message: "System.Exception: 'Existing employee could not be deleted System.InvalidOperationException: Collection was modified; enumeration operation may not execute." What is a problem? How to fix it? Thanks.
Add .ToList()
after deleteEmp.EmployeeTasks
foreach (EmployeeTask empTask in deleteEmp.EmployeeTasks.ToList())
{
context.EmployeeTasks.Remove(empTask);
}
Could you try like this, but replace i.parentId
for real navigation property
try
{
using (var context = new Model1())
{
var deleteEmp = context.EmployeeDept.FirstOrDefault(i => i.id == deletedEmpId);
var childEmps = context.EmployeeDept.Where(i => i.parentId == deletedEmpId).ToList();
context.EmployeeDepts.RemoveRange(childEmps);
context.EmployeeDepts.Remove(deleteEmp);
context.SaveChanges();
}
}
catch (Exception ex)
{
throw new Exception("Existing employee could not be deleted " + ex.ToString());
}
In Entity Framework you can only Remove
items that are in the DbContext.ChangeTracker
. Every item in the ChangeTracker has a State that says whether it is Added / Modified / Removed.
When you call SaveChanges, the ChangeTracker is checked to see which items must be updated.
Whenever you fetch a complete items, so without using Select
, the item is automatically stored in the ChangeTracker. There are other methods to add items to the change tracker, but those are out of scope of this question.
So all you need to do, is fetch all items that you want to Remove, before you remove them.
So you have Employees
and EmployeeTasks
. Apparently there is a one-to-many relation between Employees
and EmployeeTasks
: every Employee
has zero or more EmployeeTasks
; every EmployeeTask
belongs to exactly one Employee
, namely the Employee
that the foreign key EmployeeId
refers to.
You need to fetch the Employee and all EmployeeTasks, remove all tasks, and then remove the Employee:
int employeeToRemoveId = ...
using (var dbContext = new EmployeeDbContext(...))
{
var employee = dbContext.Employees.Find(employeeToRemoveId);
if (employee != null)
{
// there is an employee with this Id. get its tasks:
var tasksOfThisEmployee = dbContext.EmployeeTasks
.Where(task=> task.EmployeeId == employeeToRemoveId)
.ToList();
// remove the tasks; remove the employee; save the changes
dbContext.EmployeeTasks.RemoveRange(tasksOfThisEmployee);
dbContext.Employees.Remove(employee);
dbContext.SaveChanges();
}
// else: there is no Employee with this Id; nothing to do.
}
Simple comme bonjour!
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.