У меня возникли некоторые проблемы с тем, как разобраться в этих отношениях и как, возможно, установить для них настройки каскадного удаления.
- Существует таблица сотрудников, где у каждого сотрудника есть любое количество ручек, вложений и заданий
- Существует таблица ручек, где каждая ручка принадлежит сотруднику и может использоваться в инструменте
- Существует таблица вложений, где каждое вложение принадлежит сотруднику и может использоваться в инструменте
- Существует таблица инструментов, где каждый инструмент состоит из одного вложения, одной ручки и используется для любого количества заданий
- Существует таблица рабочих мест, где каждая работа принадлежит работнику, и может иметь или не иметь инструмент, используемый на нем
Примечание: ручки и вложения могут существовать без использования инструмента
Короче говоря: сотрудник может смешивать и сочетать ручки и вложения для создания инструментов, а затем использовать инструмент в назначенном ему задании.
На этой диаграмме показано, как база данных соединена вместе (, не стесняйтесь, предложите лучший дизайн )
Диаграмма БД
Так настроены модели. Модель задания имеет нулевую ссылку на инструменты FK (ToolId), поэтому задание может существовать без инструмента.
public class Employee
{
public int EmployeeId { get; set; }
public string Name { get; set; }
public List<Handle> Handles { get; set; }
public List<Attachment> Attachments { get; set; }
public List<Job> Jobs { get; set; }
}
public class Handle
{
public int HandleId { get; set; }
public string Material { get; set; }
public double ExpectedLife { get; set; }
public double LifetimeMaintenance { get; set; }
public int EmployeeId { get; set; }
public Employee Employee { get; set; }
public List<Tool> Tools { get; set; }
}
public class Attachment
{
public int AttachmentId { get; set; }
public string Material { get; set; }
public string Type { get; set; }
public double ExpectedLife { get; set; }
public double LifetimeMaintenance { get; set; }
public int EmployeeId { get; set; }
public Employee Employee { get; set; }
public List<Tool> Tools { get; set; }
}
public class Tool
{
public int ToolId { get; set; }
public string OperationSpeed { get; set; }
public int HandleId { get; set; }
public Handle Handle { get; set; }
public int AttachmentId { get; set; }
public Attachment Attachment { get; set; }
public List<Job> Jobs { get; set; }
}
public class Job
{
public int JobId { get; set; }
public string Name { get; set; }
public double EffortRequired { get; set; }
public int EmployeeID { get; set; }
public Employee Employee { get; set; }
public int? ToolId { get; set; }
public Tool Tool { get; set; }
}
Вот как был создан контекст БД. Существует параметр каскадного удаления, позволяющий установить для инструмента FK в Jobs (ToolId) значение NULL при удалении инструмента (поэтому задание не будет удалено при удалении его инструмента).
public class ToolsDbContext : DbContext
{
public ToolsDbContext(DbContextOptions<ToolsDbContext> options) : base(options)
{
}
public DbSet<Employee> employees { get; set; }
public DbSet<Handle> handles { get; set; }
public DbSet<Attachment> attachments { get; set; }
public DbSet<Tool> tools { get; set; }
public DbSet<Job> jobs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Tool>()
.HasMany(j => j.Jobs)
.WithOne(t => t.Tool)
.OnDelete(DeleteBehavior.SetNull);
}
}
Создание миграции работает, но затем обновление базы данных завершается неудачно со следующей ошибкой:
Introducing FOREIGN KEY constraint 'FK_tools_handles_HandleId' on table 'tools' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint or index. See previous errors.
Я не совсем уверен, как понять эту ошибку.
Обдумав это:
- Если дескриптор удален, он удалит все инструменты, в которых он используется, что, в свою очередь, установит для ToolId в связанных заданиях значение null
- Если вложение будет удалено, оно удалит все инструменты, в которых оно используется, что, в свою очередь, установит для ToolId в связанных заданиях значение null
- Если инструмент удален, он установит ToolId в связанных заданиях на null
- Если задание удалено, каскадный эффект не будет
Поэтому я думаю, что проблема должна быть в удалении сотрудника, но я не понимаю, почему (пока?) ...
- Если сотрудник удален, все должно быть удалено; он должен удалить все связанные задания, дескрипторы и вложения. Затем эти удаленные дескрипторы или вложения должны, в свою очередь, удалить связанные с ними инструменты (не важно, что было первым).
Так что есть каскадные пути удаления сотрудника, но я ожидаю, что все это будет работать на основе настройки модели как есть ... Так что мне нужно настроить больше требований каскадного удаления в dbcontext? Если так, я не уверен, как это должно быть настроено ...
Примечание: без модели сотрудников в базе данных все вроде бы работает