Ниже приведены мои 2 класса, разделяющие отношения от 1 до многих:
public partial class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Skills> Skills { get; set; }
}
public partial class Skills
{
public int Id { get; set; }
public Nullable<int> EmployeeId { get; set; }
public string Skills { get; set; }
public virtual Employee Employee { get; set; }
}
Теперь я пытаюсь удалить сотрудников с соответствующими навыками следующим образом:
1) Удаление как сотрудника, так и навыков одним методом с сохранением только изменений. Я предполагаю, что в этом случае у меня будет преимущество в производительности, так как мне нужно вызвать сохранение изменений только один раз, но есть также 1 проблема: если навыки были удалены, но если при удалении сотрудника возникает ошибка, в этом случае я буду потерять Навыки соответствующего Сотрудника.
public void Delete(int[] ids)
{
using (var context = new MyEntities())
{
context.Skills.RemoveRange(context.Skills.Where(cd => ids.Contains(cd.EmployeeId)));
context.Employee.RemoveRange(context.Employee.Where(t => ids.Contains(t.Id)));
context.SaveChanges();
}
}
2) Другой вариант — использовать транзакцию, чтобы убедиться, что оба и дочерние элементы успешно удалены, как показано ниже:
public HttpResponseMessage Delete(int[] ids)
{
using (var context = new MyEntities())
{
using (var transaction = context.Database.BeginTransaction())
{
try
{
DeleteSkills(ids,context);
DeleteEmployees(ids,context);
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
// throw exception.
}
}
}
}
public void DeleteEmployees(int[] ids,MyEntities _context)
{
_context.Employee.RemoveRange(_context.Employee.Where(t => ids.Contains(t.Id)));
_context.SaveChanges();
}
public void DeleteSkills(int[] ids, MyEntities _context)
{
_context.Skills.RemoveRange(_context.Skills.Where(cd => ids.Contains(cd.EmployeeId)));
_context.SaveChanges();
}
3) Я ищу вариант, при котором мне не нужно явно удалять дочерний элемент (навыки), а дочерний элемент удаляется автоматически на основе удаления родительского (сотрудника) объекта, как это происходит в случае первого каскадного кода при удалении, чтобы Мне не нужно запускать 2 запроса для удаления родительского и дочернего элементов (мой первый вариант) или мне не нужно поддерживать транзакцию (мой второй вариант).
Я провел некоторое исследование, но не смог найти никакой помощи по автоматическому удалению дочерних элементов на основе удаления родителя в случае первого подхода к базе данных (.edmx).
Каков эффективный способ справиться с этим сценарием?
DbContext.SaveChanges
сам использует транзакцию, поэтому вам не нужно беспокоиться о частичном удалении в случае 1 - person Sam I am says Reinstate Monica   schedule 27.09.2017