Я боролся с этим некоторое время и не могу понять, что происходит. У меня есть сущность Карты, которая содержит Стороны (обычно 2), и у обеих карт и Сторон есть Сцена. Я использую EF Codefirst миграции, и миграции завершаются с ошибкой:
Введение ограничения FOREIGN KEY 'FK_dbo.Sides_dbo.Cards_CardId' в таблицу 'Sides' может привести к возникновению циклов или нескольких каскадных путей. Укажите ON DELETE NO ACTION или ON UPDATE NO ACTION или измените другие ограничения FOREIGN KEY.
Вот моя сущность карты :
public class Card
{
public Card()
{
Sides = new Collection<Side>();
Stage = Stage.ONE;
}
[Key]
[Required]
public virtual int CardId { get; set; }
[Required]
public virtual Stage Stage { get; set; }
[Required]
[ForeignKey("CardId")]
public virtual ICollection<Side> Sides { get; set; }
}
Вот моя сторона :
public class Side
{
public Side()
{
Stage = Stage.ONE;
}
[Key]
[Required]
public virtual int SideId { get; set; }
[Required]
public virtual Stage Stage { get; set; }
[Required]
public int CardId { get; set; }
[ForeignKey("CardId")]
public virtual Card Card { get; set; }
}
А вот и мой Сценический объект:
public class Stage
{
// Zero
public static readonly Stage ONE = new Stage(new TimeSpan(0, 0, 0), "ONE");
// Ten seconds
public static readonly Stage TWO = new Stage(new TimeSpan(0, 0, 10), "TWO");
public static IEnumerable<Stage> Values
{
get
{
yield return ONE;
yield return TWO;
}
}
public int StageId { get; set; }
private readonly TimeSpan span;
public string Title { get; set; }
Stage(TimeSpan span, string title)
{
this.span = span;
this.Title = title;
}
public TimeSpan Span { get { return span; } }
}
Что странно, если я добавлю следующее в свой класс Stage:
public int? SideId { get; set; }
[ForeignKey("SideId")]
public virtual Side Side { get; set; }
Миграция проходит успешно. Если я открою SSMS и посмотрю на таблицы, я вижу, что Stage_StageId
оно было добавлено Cards
(как ожидалось / желательно), однако не Sides
содержит ссылки на Stage
(не ожидается).
Если я тогда добавлю
[Required]
[ForeignKey("StageId")]
public virtual Stage Stage { get; set; }
public int StageId { get; set; }
В моем классе Side я вижу StageId
столбец, добавленный в мою Side
таблицу.
Это работает, но теперь во всем моем приложении любая ссылка на Stage
содержит SideId
, что в некоторых случаях совершенно не имеет значения. Я хотел бы просто дать моим Card
и Side
сущностям Stage
свойство, основанное на вышеуказанном классе Stage, не загрязняя класс stage ссылочными свойствами, если это возможно ... что я делаю неправильно?
Side
классе добавьте целое число,[Required]
public int? CardId { get; set; }
DeleteBehavior.Restrict
илиDeleteBehavior.SetNull
.Ответы:
Поскольку
Stage
это необходимо , для всех взаимосвязей «один ко многим», в которыхStage
это происходит, будет включено каскадное удаление по умолчанию. Это означает, что если вы удалитеStage
объектSide
Card
и потомуCard
и будетSide
иметь обязательное отношение «один ко многим» с каскадным удалением, включенным по умолчанию снова, затем оно будет каскадно переходитьCard
кSide
Итак, у вас есть два каскадных пути удаления из
Stage
в,Side
что вызывает исключение.Вы должны либо сделать
Stage
необязательный, по крайней мере, один из объектов (то есть удалить[Required]
атрибут изStage
свойств), либо отключить каскадное удаление с помощью Fluent API (невозможно с аннотациями данных):источник
Stage
. Другие отношения остаются неизменными.Stage
удаление может каскадноSide
проходить как напрямую, так и черезCard
У меня был стол, который имел круговые отношения с другими, и я получал ту же ошибку. Оказывается, речь идет о внешнем ключе, который не обнулялся. Если ключ не имеет значения NULL, связанный объект должен быть удален, а циклические отношения не допускают этого. Так что используйте обнуляемый внешний ключ.
источник
int?
вместо того,int
чтобы позволить ему быть обнуляемым.Любой, кто интересуется, как это сделать в ядре EF:
источник
builder.HasOne(x => x.Stage).WithMany().HasForeignKey(x => x.StageId).OnDelete(DeleteBehavior.Restrict);
builder _ .Entity<TEntity>() _
прежде чемHasOne()
можно вызвать ...IEntityTypeConfiguration<T>
. Я не помню, чтобы виделbuilder.Entity<T>
метод в те дни, но я могу ошибаться. Тем не менее, они оба будут работать :)Я получал эту ошибку для многих объектов, когда переходил с модели EF7 на версию EF6. Я не хотел проходить каждую сущность по одному, поэтому я использовал:
источник
Вы можете установить для cascadeDelete значение false или true (в вашем методе Up () миграции). Зависит от вашего требования.
источник
UP
метод может быть изменен внешними операциями.В .NET Core я изменил параметр onDelete на ReferencialAction.NoAction
источник
У меня была эта проблема также, я решил это мгновенно с этим ответом из аналогичной темы
В моем случае я не хотел удалять зависимую запись при удалении ключа. Если это так, то просто измените логическое значение в миграции на false:
Скорее всего, если вы создаете отношения, которые выдают эту ошибку компилятора, но НЕ хотите поддерживать каскадное удаление; у вас есть проблема с вашими отношениями.
источник
Я исправил это. Когда вы добавляете миграцию, в методе Up () будет такая строка:
Если вы просто удалите cascadeDelete с конца, он будет работать.
источник
Просто для целей документирования, для кого-то, кто придет в будущем, эта вещь может быть решена так же просто, как этот, и с помощью этого метода вы можете сделать метод, который отключен один раз, и вы можете получить доступ к своему методу в обычном режиме.
Добавьте этот метод в класс контекстной базы данных:
источник
Это звучит странно, и я не знаю почему, но в моем случае это происходило потому, что моя ConnectionString использовала "." в атрибуте «источник данных». Как только я изменил его на "localhost", он заработал как шарм. Никаких других изменений не было.
источник
В .NET Core я играл со всеми верхними ответами - но безуспешно. Я внес много изменений в структуру БД и каждый раз добавлял новые попытки миграции
update-database
, но получал одну и ту же ошибку.Затем я начал
remove-migration
один за другим, пока консоль диспетчера пакетов не выдавала мне исключение:После этого я добавил новую миграцию (
add-migration
) иupdate-database
успешноТаким образом, мое предложение было бы: очистить все ваши временные миграции, до вашего текущего состояния БД.
источник
Существующие ответы великолепны. Я просто хотел добавить, что столкнулся с этой ошибкой по другой причине. Я хотел создать начальную миграцию EF для существующей БД, но я не использовал флаг -IgnoreChanges и применил команду Update-Database для пустой базы данных (также для существующих сбоев).
Вместо этого мне пришлось выполнить эту команду, когда текущая структура БД является текущей:
Вероятно, существует реальная проблема в структуре БД, но спасите мир по одному шагу за раз ...
источник
Простой способ, редактировать файл миграция
(cascadeDelete: true)
в(cascadeDelete: false)
то после назначения команды Update-Database в вашем Package Manager Console.if это проблема с вашей последней миграцией , то все в порядке. В противном случае проверьте свою предыдущую историю миграции, скопируйте эти вещи, вставьте в последний файл миграции, после чего сделайте то же самое. это прекрасно работает для меня.источник
Если миграция завершается неудачно, вам предоставляется несколько вариантов: «Введение ограничения FOREIGN KEY» FK_dbo.RecommendedBook_dbo.Department_DepartmentID »в таблице« RecommendedBook »может вызывать циклы или несколько каскадных путей. Укажите ON DELETE NO ACTION или ON UPDATE NO ACTION или измените другие ограничения FOREIGN KEY. Не удалось создать ограничение или индекс. Смотрите предыдущие ошибки.
Вот пример использования «изменить другие ограничения FOREIGN KEY», установив для «cascadeDelete» значение false в файле миграции, а затем запустив «update-database».
источник
Ни одно из вышеупомянутых решений не помогло мне. То, что мне нужно было сделать, это использовать обнуляемый int (int?) Для внешнего ключа, который не требовался (или не является ненулевым ключом столбца), а затем удалить некоторые из моих миграций.
Начните с удаления миграций, затем попробуйте обнуляемый int.
Проблемой была как модификация, так и дизайн модели. Нет необходимости в изменении кода.
источник
Сделайте ваши атрибуты внешнего ключа обнуляемыми. Это будет работать.
источник