Введение ограничения внешнего ключа может вызвать циклы [duplicate]

  / ** В этой программе будет отображаться заданный номер в словах от 0 до 999999999 @author Manoj Kumar Dunna Mail Id: manojdunna@gmail.com ** / import java.util.Scanner;  class NumberToString {public enum hundred {Столбцы, сотни, три сотни, четыре сотни, пятьсот, шестьсот, семьсот, восемьсот, девятьсот) публичные перечисления десятки {Двадцать, тридцать, сорок, пятьдесят, шестьдесят, семьдесят, восемьдесят, девяносто} публичных перечислений {One  , Два, Три, Четыре, Пять, Шесть, Семь, Восемь, Девять} общедоступный enum denom {Thousand, Lakhs, Crores} public enum splNums {Десять, Одиннадцать, Двенадцать, Тринадцать, Четырнадцать, Пятнадцать, Шестнадцать, Семнадцать, Восемнадцать, Девятнадцать  } public static String text = "";  public static void main (String [] args) {System.out.println ("Введите число для преобразования в слова");  Сканер sc = новый сканер (System.in);  long num = sc.nextInt ();  int rem = 0;  int i = 0;  while (num & gt; 0) {if (i == 0) {rem = (int) (num% 1000);  printText (бэр);  num = num / 1000;  я ++;  } else if (num & gt; 0) {rem = (int) (num% 100);  if (rem & gt; 0) text = denom.values ​​() [i-1] + "" + текст;  printText (бэр);  num = num / 100;  я ++;  }} if (i & gt; 0) System.out.println (текст);  else System.out.println («Zero»);  } public static void printText (int num) {if (! (num & gt; 9 & amp; num & lt; 19)) {if (num% 10 & gt; 0) getOnes (num% 10);  num = num / 10;  если (num% 10 & gt; 0) getTens (num% 10);  num = num / 10;  if (num & gt; 0) getHundreds (num);  } else {getSplNums (num% 10);  }} public static void getSplNums (int num) {text = splNums.values ​​() [num] + "" + текст;  } public static void getHundreds (int num) {text = hundreds.values ​​() [num - 1] + "" + текст;  } public static void getTens (int num) {text = tens.values ​​() [num - 2] + "" + текст;  } public static void getOnes (int num) {text = ones.values ​​() [num - 1] + "" + текст;  }}  
217
задан SB2055 15 June 2013 в 20:52
поделиться

13 ответов

Поскольку Stage является обязательным , все отношения «один ко многим», в которых задействован Stage, будут иметь каскадное удаление по умолчанию. Это означает, что если вы удалите объект Stage

  • , удаление будет каскадом непосредственно на Side
  • , удаление будет каскадом непосредственно на Card и потому что Card и Side имеют обязательные отношения один-ко-многим с каскадным удалением, включенным по умолчанию, затем он будет каскадом от Card до Side

Итак, у вас есть два каскадных удалить пути из Stage в Side - что вызывает исключение.

Вы должны либо сделать Stage необязательным, по крайней мере, в одном из объектов (т. е. удалить атрибут [Required] из Stage) или отключить каскадное удаление с помощью Fluent API (невозможно с аннотациями данных):

modelBuilder.Entity<Card>()
    .HasRequired(c => c.Stage)
    .WithMany()
    .WillCascadeOnDelete(false);

modelBuilder.Entity<Side>()
    .HasRequired(s => s.Stage)
    .WithMany()
    .WillCascadeOnDelete(false);
300
ответ дан Riz 16 August 2018 в 02:44
поделиться
  • 1
    Спасибо Слауме. Если я использую свободный API, как вы продемонстрировали выше, будут ли другие поля сохранять каскадное поведение удаления? Мне все еще нужно, чтобы стороны были удалены, например, когда удалены карты. – SB2055 15 June 2013 в 21:53
  • 2
  • 3
    Есть ли способ узнать, какие свойства вызывают ошибку? У меня такая же проблема, и, глядя на мои классы, я не вижу, где цикл – Rodrigo Juarez 27 May 2017 в 01:00
  • 4
    Является ли это ограничением в их реализации? Мне кажется, что для удаления Stage для каскада до Side как напрямую, так и через Card – aaaaaa 4 July 2017 в 22:20

Ни один из вышеупомянутых решений не работал для меня. Мне нужно было использовать nullable int (int?) Для внешнего ключа, который не был необходим (или не был не нулевым столбцом), а затем удалить некоторые из моих миграций.

Начните с удаления миграции, затем попробуйте ввести значение null.

Проблема была как модификацией, так и моделью. Не требуется изменение кода.

0
ответ дан Ayson Baxter 16 August 2018 в 02:44
поделиться

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

[ForeignKey("StageId")]
public virtual Stage Stage { get; set; }
public int? StageId { get; set; }
36
ответ дан Cem Mutlu 16 August 2018 в 02:44
поделиться
  • 1
    Я удалил тэг [Required], но важнее было использовать int? вместо int, чтобы он был нулевым. – VSB 28 March 2016 в 17:45
  • 2
    Я пробовал много разных способов отключения каскадного удаления и ничего не работал - это исправлено! – ambog36 5 October 2016 в 20:57
  • 3
    Вам не следует делать это, если вы не хотите, чтобы Stage был установлен на null (этап был обязательным полем в исходном вопросе). – cfwall 15 November 2017 в 11:26

Существующие ответы велики, я просто хотел добавить, что я столкнулся с этой ошибкой по другой причине. Я хотел создать начальную миграцию EF в существующей БД, но я не использовал флаг -IgnoreChanges и применил команду Update-Database в пустой базе данных (также при существующих сбоях).

Вместо этого я должен был выполнить эту команду, когда текущая структура db является текущей:

Add-Migration Initial -IgnoreChanges

В структуре db существует реальная проблема, но сохранить мир за один шаг за раз ...

1
ответ дан CodingYourLife 16 August 2018 в 02:44
поделиться

У меня тоже была эта проблема, я сразу же решил ее с помощью этого ответа из аналогичного потока

. В моем случае я не хотел удалять зависимую запись по ключу удаление. Если это имеет место в вашей ситуации, просто просто измените значение Boolean при переходе на false:

AddForeignKey("dbo.Stories", "StatusId", "dbo.Status", "StatusID", cascadeDelete: false);

Скорее всего, если вы создаете отношения, которые генерируют эту ошибку компилятора, но DO хотят сохранить каскадное удаление ; у вас есть проблема с вашими отношениями.

5
ответ дан Hakam Fostok 16 August 2018 в 02:44
поделиться

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

Добавьте этот метод в класс базы данных контекста:

protected override void OnModelCreating(DbModelBuilder modelBuilder) {
    modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}
1
ответ дан john 16 August 2018 в 02:44
поделиться

Это звучит странно, и я не знаю почему, но в моем случае это происходило, потому что мой ConnectionString использовал «.». в атрибуте «источник данных». Как только я изменил его на «localhost», он работал как шарм. Никаких других изменений не было.

1
ответ дан Marco Alves 16 August 2018 в 02:44
поделиться
  • 1
    Голосование без рекламы даже отвратительно – Marco Alves 13 July 2016 в 13:07

В .NET Core я изменил параметр onDelete на ReferencialAction.NoAction

         constraints: table =>
            {
                table.PrimaryKey("PK_Schedule", x => x.Id);
                table.ForeignKey(
                    name: "FK_Schedule_Teams_HomeId",
                    column: x => x.HomeId,
                    principalTable: "Teams",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.NoAction);
                table.ForeignKey(
                    name: "FK_Schedule_Teams_VisitorId",
                    column: x => x.VisitorId,
                    principalTable: "Teams",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.NoAction);
            });
1
ответ дан Mike Jones 16 August 2018 в 02:44
поделиться

Вы можете установить cascadeDelete в false или true (в методе миграции Up ()). Зависит от вашего требования.

AddForeignKey("dbo.Stories", "StatusId", "dbo.Status", "StatusID", cascadeDelete: false);
14
ответ дан Nazim Turakulov 16 August 2018 в 02:44
поделиться
  • 1
    @ Муссакхир благодарит вас за ответ. Ваш путь очень изящный и более сложный - он более точный и нацелен непосредственно на проблему, с которой я столкнулся! – Nazim Turakulov 2 June 2016 в 07:03

Кто-нибудь задается вопросом, как это сделать в ядре EF:

      protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                foreach (var relationship in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
                {
                    relationship.DeleteBehavior = DeleteBehavior.Restrict;
                }
           ..... rest of the code.....
19
ответ дан Nexus23 16 August 2018 в 02:44
поделиться
  • 1
    Ты легенда, спасибо за публикацию этого! Я все время теряюсь в разных версиях, это именно то, что я искал – Jordan Wallwork 3 March 2017 в 19:32
  • 2
    Во-вторых, это! Спасибо. – Sam 31 March 2017 в 18:20
  • 3
    Это отключит каскадное удаление во всех отношениях. Каскадное удаление может быть желательным для некоторых случаев использования. – Blaze 6 June 2017 в 10:29
  • 4
    Альтернативно, builder.HasOne(x => x.Stage).WithMany().HasForeignKey(x => x.StageId).OnDelete(DeleteBehavior.Restrict); – Biscuits 4 April 2018 в 11:30

В .NET Core я играл со всеми верхними ответами - но без каких-либо успехов. Я много изменил структуру БД и каждый раз добавлял новую попытку миграции в update-database, но получал ту же ошибку.

Затем я начал remove-migration один за другим, пока Консоль диспетчера пакетов бросил мне исключение:

Миграция '20170827183131 _ ***' уже была применена к базе данных

. После этого я добавил новую (add-migration) и update-database успешно

Таким образом, мое предложение было бы: очистить все ваши временные миграции до вашего текущего состояния БД.

0
ответ дан rock_walker 16 August 2018 в 02:44
поделиться

Я получал эту ошибку для многих объектов, когда я переносился с модели EF7 на версию EF6. Я не хотел проходить каждую сущность по одному, поэтому я использовал:

builder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
builder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
19
ответ дан Sean 16 August 2018 в 02:44
поделиться
  • 1
    Это должно быть добавлено в классах (классах), которые наследуются от DbContext, например. в методе OnModelCreating. Строитель имеет тип DbModelBuilder – CodingYourLife 15 December 2017 в 10:35
  • 2
    Это сработало для меня; .NET 4.7, EF 6. Один камнем преткновения я получил ошибку, поэтому, когда я восстановил сценарий миграции с удалением этих соглашений, он не помог. Запуск «Add-Migration» с "-Force" очистил все это и перестроил его, включая вышеупомянутые соглашения. Задача решена... – James Joyce 14 June 2018 в 16:35

Я исправил это. Когда вы добавите миграцию, в методе Up () появится строка, подобная этой:

.ForeignKey («dbo.Members», t => t.MemberId, cascadeDelete: True)

Если вы просто удалите cascadeDelete с конца, он будет работать.

1
ответ дан Usman Khan 16 August 2018 в 02:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: