Существуют различные способы структурирования ваших сущностей, которые облегчают эту задачу, однако для начала давайте добавим метод к вашему классу SubjectsDbContext
, чтобы использовать плавную запись для обеспечения поведения каскадного удаления:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Normally these conventions should easily target your entire model to support cascade delete
//modelBuilder.Conventions.Add(new OneToManyCascadeDeleteConvention());
//modelBuilder.Conventions.Add(new ManyToManyCascadeDeleteConvention());
// However you many not want the entire model to cascade,
// or due to the relationshipships not being explicitly defined so the above conventions
// may not resolve correctly.
// These statements explicitly define the relationships and the cascade operation
modelBuilder.Entity<Subject>().HasMany(x => x.KeyValues).WithRequired().WillCascadeOnDelete(true);
modelBuilder.Entity<Subject>().HasRequired(x => x.EnrolledFace).WithRequiredPrincipal().WillCascadeOnDelete(true);
}
Кажется, ваша модель имеет минимальные поля, необходимые для ее поддержки, однако вы не включили никаких внешних ключей в таблицы Зависимые , поэтому модель не знает о том, что записи ДОЛЖНЫ зависят от их связи с Subject
.
Фактически, НЕ , определяющей отношение, модель предполагает , что связанный ключи, которые он генерирует от вашего имени, на самом деле являются необязательными , что означает, что записи FaceImage
и KVPair
должны существовать сами по себе, не связанные с Subject
.
Добавление ссылок на внешний ключ в FaceImage
и KVPair
уменьшает двусмысленность:
ПРИМЕЧАНИЕ: здесь добавлены только свойства навигации
public class FaceImage
{
...
[Required]
public virtual Subject Subject { get; set; }
}
public class KVPair
{
...
[Required]
public virtual Subject Subject { get; set; }
}
С этим изменением, бить Для определения этих взаимосвязей в методе OnModelCreating
нам нужно немного изменить беглую запись:
modelBuilder.Entity<Subject>().HasMany(x => x.KeyValues).WithRequired(x => x.Subject).WillCascadeOnDelete(true);
modelBuilder.Entity<Subject>().HasRequired(x => x.EnrolledFace).WithRequiredPrincipal(x => x.Subject).WillCascadeOnDelete(true);
(Или вы можете просто откомментировать строки, которые добавляют delete cascade условные обозначения. )
Это окончательный вывод, если вам нужен доступ к фактическим полям Внешний ключ , которые используются для принудительного применения навигационных ссылок, или если это Code First реализации, и вы хотите влиять на имена этих полей, затем вы просто добавляете эти поля в классы:
public class FaceImage
{
...
[Required]
public Guid SubjectId { get; set; }
[ForeignKey(nameof(SubjectId))]
public virtual Subject Subject { get; set; }
}
public class KVPair
{
...
[Required]
public Guid SubjectId { get; set; }
[ForeignKey(nameof(SubjectId))]
public virtual Subject Subject { get; set; }
}