У меня есть три объекта: Boss
, Employee
и Instruction
.У боссов есть набор инструкций, которые они могут выдавать (отношения один-ко-многим), а у боссов есть набор сотрудников (отношения один-ко-многим), которым они могут давать эти инструкции.Инструкция может быть дана более чем одному Сотруднику, поэтому между Сотрудниками и Инструкцией существует отношение многие ко многим.Итак, вот мои сущности:
public class Boss
{
public int ID { get; set; }
public string Name { get; set; }
public ICollection<Instruction> Instructions { get; set; }
public ICollection<Employee> Employees { get; set; }
}
public class Employee
{
public int ID { get; set; }
public int BossID { get; set; }
public string Name { get; set; }
public DateTime WorkTime { get; set; }
public ICollection<Instruction> Instructions { get; set; }
}
public class Instruction
{
public int ID { get; set; }
public string Name { get; set; }
public int BossID { get; set;}
public ICollection<Employee> Employees { get; set; }
}
Цель состоит в том, чтобы написать запросы для получения списков сотрудников босса, а также посмотреть, какие сотрудники назначены для каждой инструкции.Дополнительная причина для его моделирования таким образом заключается в том, что мы можем применять ограничения уникальности, чтобы, например, у нас не было одного и того же сотрудника, введенного несколько раз, и, возможно, мы не хотим, чтобы босс планировал работать с несколькими сотрудниками.в то же время.Итак, вот DbContext с этими отношениями, отображаемыми с помощью Fluent API:
public class Model1 : DbContext
{
public Model1() : base("name=Model1") { }
public virtual DbSet<Boss> Bosses { get; set; }
public virtual DbSet<Instruction> Instructions { get; set; }
public virtual DbSet<Employee> Employees { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
modelBuilder.Entity<Employee>().HasMany<Instruction>(x => x.Instructions).WithMany(x => x.Employees);
modelBuilder.Entity<Boss>().HasMany<Instruction>(x => x.Instructions);
modelBuilder.Entity<Boss>().HasMany<Employee>(x =>x.Employees);
modelBuilder.Entity<Employee>().Property(x => x.BossID)
.HasColumnAnnotation(IndexAnnotation.AnnotationName,
new IndexAnnotation(new IndexAttribute("OneEmployeeAtATime", 0) { IsUnique = true }));
modelBuilder.Entity<Employee>().Property(x => x.WorkTime)
.HasColumnAnnotation(IndexAnnotation.AnnotationName,
new IndexAnnotation(new IndexAttribute("OneEmployeeAtATime", 1) { IsUnique = true }));
base.OnModelCreating(modelBuilder);
}
}
Строка modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
находится там, потому что в противном случае я получаю ошибку «несколько каскадных путей».Я хочу, чтобы при удалении Boss
он также удалял его Employees
и Instructions
, но если я удаляю либо Instruction
, либо Employee
, он не должен каскадироваться.Но когда я запускаю свой тест:
using (Model1 db = new Model1())
{
Boss boss = db.Bosses.First();
db.Bosses.Remove(boss);
db.SaveChanges();
}
, я получаю это сообщение об ошибке:
System.Data.Entity.Infrastructure.DbUpdateException: при обновлении записей произошла ошибка.Смотрите внутреннее исключение для деталей.---> System.Data.Entity.Core.UpdateException: при обновлении записей произошла ошибка.Смотрите внутреннее исключение для деталей.---> System.Data.SqlClient.SqlException: инструкция DELETE вступила в конфликт с ограничением REFERENCE "FK_dbo.EmployeeInstructions_dbo.Employees_Employee_ID".Конфликт произошел в базе данных «Model1», таблице «dbo.EmployeeInstructions», столбце «Employee_ID».Утверждение было прекращено.
Я что-то упустил в Fluent API?