Ядро EF — введение ограничения ВНЕШНЕГО КЛЮЧА может привести к циклам или нескольким каскадным путям

#.net #sql-server #entity-framework-core

#.net #sql-сервер #entity-framework-core

Вопрос:

Я получаю Introducing FOREIGN KEY constraint 'FK_ExchangeHours_Times_StartTimeId' on table 'ExchangeHours' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. сообщение об ошибке при попытке обновить базу данных через EF Core до MSSQLServer. Проблема заключается в классе ExchangeHour, который ссылается на время занятий.

Классы:

 public class ExchangeHour
{
    ...
    public int StartTimeId { get; set; }
    public Time StartTime { get; set; }
    public int EndTimeId { get; set; }
    public Time EndTime { get; set; }
    ...
}

public class Time
{
    public int TimeId { get; set; }
    public int Hours { get; set; }
    public int Minutes { get; set; }
    public int Seconds { get; set; }
}
  

MigrationScript в отношении ExhangeHours.

 migrationBuilder.CreateTable(
                name: "ExchangeHours",
                columns: table => new
                {
                    ExchangeId = table.Column<string>(nullable: false),
                    DayOfWeek = table.Column<int>(nullable: false),
                    StartTimeId = table.Column<int>(nullable: false),
                    EndTimeId = table.Column<int>(nullable: false),
                    HourTypeId = table.Column<int>(nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_ExchangeHours", x => new { x.ExchangeId, x.DayOfWeek });
                    table.ForeignKey(
                        name: "FK_ExchangeHours_Times_EndTimeId",
                        column: x => x.EndTimeId,
                        principalTable: "Times",
                        principalColumn: "TimeId",
                        onDelete: ReferentialAction.Cascade);
                    table.ForeignKey(
                        name: "FK_ExchangeHours_Exchanges_ExchangeId",
                        column: x => x.ExchangeId,
                        principalTable: "Exchanges",
                        principalColumn: "Id",
                        onDelete: ReferentialAction.Cascade);
                    table.ForeignKey(
                        name: "FK_ExchangeHours_ExchangeHourTypes_HourTypeId",
                        column: x => x.HourTypeId,
                        principalTable: "ExchangeHourTypes",
                        principalColumn: "Id",
                        onDelete: ReferentialAction.Cascade);
                    table.ForeignKey(
                        name: "FK_ExchangeHours_Times_StartTimeId",
                        column: x => x.StartTimeId,
                        principalTable: "Times",
                        principalColumn: "TimeId",
                        onDelete: ReferentialAction.Cascade);
                });
  

Когда ExchangeHour будет удален, я хочу удалить обе ссылки на время, так как они мне больше не понадобятся, поэтому каскад при удалении — это то, что я хочу. Но если я удалю одну из ссылок на время занятий, update-migrations выполняется без ошибок. Я не вижу в этом никакого цикла или чего-то плохого, поэтому я не совсем уверен, почему я не могу это использовать. Я не нашел никаких ограничений, что один класс не может ссылаться на другой несколько раз. Есть идеи, почему это выдает эту ошибку?

Комментарии:

1. Какая связь между ExchangeHour и Time ? от 1 ExchangeHour до 1 Time или 1 Time может быть связано с несколькими ExchangeHour

2. ExchangeHour может иметь 2 Time , 1 Time может быть связано с 1 ExchangeHour

3. Ну, кажется, это известная проблема некоторых SQL-серверов, вы можете подробнее прочитать об этом по следующей ссылке github.com/dotnet/efcore/issues/5871 . Цитата оттуда unfortunately some relational databases, notably SQL Server, do not support having multiple cascade relationships . Там вы можете найти возможный обходной путь обработки каскада в коде.

4. Спасибо, я искал, может ли быть что-то подобное, но ничего не нашел, спасибо за ссылку.

5. Итак, нет, циклов нет, но есть несколько каскадных путей. Нет способа избежать этой ошибки, кроме удаления одного каскадного удаления и обработки каскадного удаления в коде. Это неприятность.