Как сделать связь обязательной в коде EF в первую очередь

У меня есть отношения EF Code First One-To-Many. По сути, это отношения «родитель-потомок», поскольку дочерний элемент не может существовать без родителя.

public class Parent
{
    [Key]
    public Guid Id { get; set; }

    public virtual ICollection<Child> Children { get; set; }

    public virtual ICollection<OtherChild> OtherChildren { get; set; }
}

public class Child
{
    [Key]
    public Guid Id { get; set; }

    public virtual Parent Parent { get; set; }
}

Поэтому я не был уверен, как я могу заставить ребенка иметь Parent, поэтому я попытался добавить к нему атрибут [Required]. Это дало мне ошибку:

- InnerException {"Introducing FOREIGN KEY constraint 'Child_Parent' on table 'Child'
  may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE
  NO ACTION, or modify other FOREIGN KEY constraints.\r\nCould not create constraint.
  See previous errors."}
  System.Exception {System.Data.SqlClient.SqlException}

Хорошо, я не уверен, как он мог иметь несколько каскадных частей.

У родителя также есть другие дочерние объекты, и эти дочерние объекты имеют отношение «многие ко многим» с исходным дочерним объектом, но для этого не требуется каскадное удаление.

Я думаю, я делаю это неправильно, но как правильно это сделать.

PS. Когда у меня есть ребенок, требующий родителя, должен ли я сделать внешний ключ частью первичного ключа?


person Ingó Vals    schedule 22.11.2011    source источник


Ответы (1)


Вы можете отключить каскадное удаление для отношения в Fluent API (это невозможно с аннотациями данных):

public class MyContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Parent>()
            .HasMany(p => p.Children)
            .WithRequired(c => c.Parent)
            .WillCascadeOnDelete(false);
    }
}

Вы также должны удалить дочерние элементы в своем коде, если вы удаляете родителя.

Вам не нужно делать внешний ключ частью первичного ключа, и я не вижу в этом выгоды. Ваш ключ Guid уже уникален. Однако это поможет повысить производительность запросов, если вы создадите индекс для столбца внешнего ключа в базе данных.

person Slauma    schedule 22.11.2011
comment
Хорошо, но как такие простые отношения могут подвергаться опасности множественных каскадных путей? - person Ingó Vals; 23.11.2011
comment
@IngóVals: я не знаю. Я протестировал вашу модель с вашими фрагментами кода и вашим дополнительным описанием. Родительский объект также имеет другие дочерние объекты, и эти дочерние объекты имеют отношение "многие ко многим" с исходным дочерним объектом. Но я вообще не получаю это исключение каскадного удаления. Возможно, я создал модель не совсем с теми отношениями, которые у вас есть. Я думаю, вы должны показать полную модель (включая сущность OtherChild), чтобы найти реальную причину исключения. - person Slauma; 23.11.2011