Представляем проблему ошибки ограничения FOREIGN KEY

Я немного смущен тем, почему я получаю эту ошибку:

Introducing FOREIGN KEY constraint 'FK_QuestionTerms_Terms_TermId' 
on table 'QuestionTerms' 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. See previous errors.

У меня есть вопрос класса и термин класса, вопросы могут иметь любое количество связанных с ними терминов, а термины могут иметь любое количество связанных с ними вопросов. Поэтому я пытаюсь создать отношения «многие ко многим» между ними. Сначала я попытался использовать соглашение и разрешил EntityFramework создать базу данных. Это класс вопросов

public class Question
{
    public Guid Id { get; set; }
    public int QuestionNumber { get; set; }
    public string StatementHtml { get; set; }
    public string AnswerHeaderHtml { get; set; }
    public string NotesHtml { get; set; }
    public Guid CategoryId { get; set; }
    public Guid CourseId { get; set; }
    public Guid QuestionTypeId { get; set; }
    public Guid? SimulationId { get; set; }
    public Guid? SimulationTabId { get; set; }

    public ICollection<Term> Terms { get; set; }
    public ICollection<ReferenceItem> ReferenceItems { get; set; }

}

А вот и класс терминов

public class Term
{
   public Guid Id { get; set; }
   public string Name { get; set; }
   public string StatementHtml { get; set; }
   public string Authority { get; set; }
   public Guid ProductId { get; set; }

   public Product Product { get; set; }
   public ICollection<Question> Questions { get; set; }
}

Я также попытался переопределить OnModelCreating следующим образом: результат обоих процессов — один и тот же код ошибки.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Question>()
        .HasMany(q => q.Terms)
        .WithMany(t => t.Questions)
        .Map(x =>
            {
                x.MapLeftKey("QuestionId");
                x.MapRightKey("TermId");
                x.ToTable("QuestionTerms");
            });
} 

person Siegeon    schedule 17.04.2012    source источник


Ответы (2)


Проблема в том, что каскадное удаление будет перемещаться между таблицами туда и обратно.

Например, сначала удалив термин A, который удалит вопросы 1, 2 и 3. Вопрос 1 также использовался в термине B, поэтому термин B должен быть удален .....

Поэтому это останавливает вас от создания таких ограничений.

Здесь хорошо описано, как это исправить: Entity Framework 4.1 InverseProperty Атрибут и внешний ключ

Изменить

Это может быть побочным эффектом других проблем. Вы должны начать с гораздо более простой модели, а затем постепенно наращивать ее.

Например:

  • Почему у вас есть и ProductId, и product
  • Почему CategoryId, а не Category...
person Shiraz Bhaiji    schedule 17.04.2012
comment
Проблема в том, что у меня нет единственного внешнего ключа между вопросом или термином. Каждый пример, который я видел, решает эту проблему, когда две таблицы связаны внешним ключом. - person Siegeon; 17.04.2012
comment
Я понимаю вашу точку зрения, может быть, я ошибаюсь в процессе; но в случае productId и product один является ассоциацией (FK), а другой — свойством навигации. Разве это не правильный способ кодирования? - person Siegeon; 17.04.2012
comment
Хотя ваш ответ не дал прямого ответа на мой вопрос, он направил меня на правильный путь. Спасибо. - person Siegeon; 17.04.2012
comment
@Sigeon, не могли бы вы также включить свой ответ, пожалуйста? - person Iain M Norman; 23.09.2012
comment
@Siegeon, не могли бы вы указать, что вы сделали, чтобы исправить это. - person jwsadler; 15.04.2013
comment
@jwsadler: прошу прощения, но это было год назад. С тех пор мы перешли на MVC и перепроектировали большие части базы данных. У меня уже нет старой кодовой базы и я не могу вспомнить специфику этого конкретного вопроса. - person Siegeon; 15.04.2013

Попробуйте добавить его в метод OnModelCreating().

  modelBuilder.Entity<Question>().HasRequired(oo => oo.Term).WithMany(oo => oo.Questions).WillCascadeOnDelete(false);
person Cinchoo    schedule 17.04.2012
comment
Когда я пробую приведенную выше конфигурацию, WithMany(oo => oo.Questions) не позволяет перейти к Вопросам; это (параметр) System.Collections.Generic.ICollection‹Term› и дает мне такие опции, как добавить, очистить и удалить. - person Siegeon; 17.04.2012