Подтвердить что ты не робот

Entity Framework Оператор ALTER TABLE противоречил ограничениям FOREIGN KEY

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

Оператор ALTER TABLE противоречил ограничению FOREIGN KEY "FK_dbo.Clients_dbo.MedicalGroups_MedicalGroupId". Конфликт произошел в базе данных "hrbc", таблице "dbo.MedicalGroups", в столбце "Id".

Это мой класс:

public partial class Client
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int? MedicalGroupId { get; set; }
    [ForeignKey("MedicalGroupId")]
    public virtual MedicalGroups MedicalGroup { get { return _MedicalGroup; } set { _MedicalGroup = value; } }
}

Вот мой второй класс:

public partial class MedicalGroups
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
}

И это моя миграция, которую я пытаюсь применить:

public override void Up()
{
    AddForeignKey("dbo.Clients", "MedicalGroupId", "dbo.MedicalGroups", "Id");
    CreateIndex("dbo.Clients", "MedicalGroupId");
}
4b9b3361

Ответ 1

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

Update Client set MedicalGroupId = NULL

Ответ 2

Убедитесь, что в базе данных нет существующих данных, которые конфликтуют с ограничением FK, что приводит к сбою создания.

Ответ 3

Я думаю, что @Cory приближает вас к правильному решению, вы просто не нашли времени для расследования.

В коде add-migration миграция, вероятно, сгенерирована

public override void Up()
{
AddColumn("dbo.ClientContacts", "FamilialRelationshipId", c => c.Int(nullable: false));
CreateIndex("dbo.ClientContacts", "FamilialRelationshipId");
AddForeignKey("dbo.ClientContacts", "FamilialRelationshipId", "dbo.FamilialRelationships",        "FamilialRelationshipId");
}

Уведомление об ошибке: false; Если ваша модель имела идентификатор int вместо int? (nullable int) код миграции устанавливает значение nullable равным false. В вашей модели показано, что вы используете non-nullable int, который по умолчанию равен 0, и вы, вероятно, не имеете элемент внешнего ключа со значением 0.

Теперь вам нужно либо создать значение по умолчанию, которое существует в таблице внешних ключей, или Создать ограничение без проверки, если вы используете SQL Server для создания ограничения. Помните об этом: если вы украшаете свою собственность атрибутом [DefaultValue (0)], она не изменит существующие данные, например, SQL Column Add, если было задано значение по умолчанию.

Я рекомендую вам изменить свой класс модели, чтобы разрешить значение с нулевым значением int. Затем в методе семян создайте простой метод против dbcontext, чтобы обновить новый столбец со значением по умолчанию, потому что атрибут [DefaultValue] в аннотациях данных не будет изменять ваши данные.

Add-Migration/Update-Database для создания столбца и ограничения. Затем измените свою модель, если вы хотите разрешить не-nullable int, и предположим, что вы снова изменили все строки на некоторое допустимое значение для внешнего ключа, Add-Migration/Update-database. Это дает вам непрерывную цепочку в вашей миграции модели. Пригодится позже, когда вы опубликуете на живой сайт, потому что поток ваших изменений модели данных будет неповрежденным.

  • Надеюсь, это поможет.

Ответ 4

Эта ошибка говорит вам, что вы нарушаете ограничение внешнего ключа. Чтобы решить, у вас есть несколько решений

  • Исправить ваши данные. Где-то в таблице Clients есть записи, в которых есть MedicalGroupId, который не существует в MedicalGroups. Напишите запрос, чтобы узнать, какие идентификаторы не существуют в таблице MedicalGroups и вручную фиксируют данные сами.
  • Удалить ограничение внешнего ключа. Очевидно, что если вы удалите ограничение внешнего ключа, это сообщение больше не будет беспокоиться. К сожалению, база данных больше не будет применять эти отношения и может ухудшить эту проблему в будущем.
  • Создать ограничение с помощью WITH NOCHECK. Вы можете создать ограничение внешнего ключа с помощью параметра WITH NOCHECK. Этот параметр указывает SQL Server не применять это ограничение к существующим данным. SQL Server будет проверять это ограничение в любом будущем INSERTS/UPDATES/DELETES.

Ответ 5

эта проблема возникает, потому что ваша таблица не пуста. поэтому вы можете добавить новое поле без привязки к нему, как к внешнему ключу. public int? MedicalGroupId {get; задавать; }. И выполните команду update-database в консоли управления пакетами. Затем заполните поле в этой таблице (клиенте) правильными данными (значение существует в MedicalGroupsId). Вставьте строку для создания внешнего ключа [ForeignKey ( "MedicalGroupId" )]   общедоступная виртуальная медицинская группа MedicalGroup {get {return _MedicalGroup; } set {_MedicalGroup = значение; }}. в конце выполните команду update-database. Это будет нормально.

Ответ 6

Для других, которые могут приземляться здесь, может быть очень простое исправление, если вы используете Code-First Entity Framework и просто пытаетесь добавить новый требуемый столбец в таблицу с существующими данными.

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

В вашей модели установите столбец в значение NULL, добавив? после инт. Сохраните и скомпилируйте модель. Запустите Update-Database.

Пример:

[ForeignKey("Title")]
public int? TitleId { get; set; }

Ответ 7

У меня была эта проблема, а также с установкой defaultValue, дал:

"Объект зависит от столбца ALTER TABLE ALTER COLUMN, потому что один или несколько объектов обращаются к этому столбцу".

Закончено переместить AddForeignKey/DropForeignKey в новую миграцию и запустить их в отдельных командах обновления базы данных (не переубеждать обе миграции в одной команде, а затем мне это не удалось.)

    public override void Up()
    {
        CreateTable(
            "dbo.DecisionAccesses",
            c => new
            {
                Id = c.Int(nullable: false),
                Name = c.String(nullable: false, maxLength: 50),
            })
            .PrimaryKey(t => t.Id);

        CreateTable(
            "dbo.DecisionPersonStatus",
            c => new
            {
                Id = c.Int(nullable: false),
                Name = c.String(nullable: false, maxLength: 50),
            })
            .PrimaryKey(t => t.Id);

        AddColumn("dbo.DecisionForm_DecisionFields", "DecisionAccessId", c => c.Int(nullable: false, defaultValue: (int)DecisionAccess.Creator));
        AddColumn("dbo.DecisionMatterPersons", "DecisionPersonStatusId", c => c.Int(nullable: false, defaultValue: (int)DecisionAccess.Creator));
        CreateIndex("dbo.DecisionForm_DecisionFields", "DecisionAccessId");
        CreateIndex("dbo.DecisionMatterPersons", "DecisionPersonStatusId");
        //I moved outcommented to next migration and ran the migrations in separate steps to avoid: (The object is dependent on column ALTER TABLE ALTER COLUMN failed because one or more objects access this column)
        //AddForeignKey("dbo.DecisionForm_DecisionFields", "DecisionAccessId", "dbo.DecisionAccesses", "Id", cascadeDelete: true); 
        //AddForeignKey("dbo.DecisionMatterPersons", "DecisionPersonStatusId", "dbo.DecisionPersonStatus", "Id", cascadeDelete: true);
    }


    public override void Down()
    {
        //Moved to next migration
        //DropForeignKey("dbo.DecisionMatterPersons", "DecisionPersonStatusId", "dbo.DecisionPersonStatus");
        //DropForeignKey("dbo.DecisionForm_DecisionFields", "DecisionAccessId", "dbo.DecisionAccesses");
    }

Ответ 8

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

  • Резервная копия текущей базы данных из студии управления SQL (при необходимости)
  • Удалить базу данных из студии управления SQL
  • Введите "Обновить-База данных" в Visual Studio "Консоль диспетчера пакетов"

Ответ 9

Запустите команду Add-Migration InitialCreate -IgnoreChanges в консоли диспетчера пакетов. Это создает пустую миграцию с текущей моделью в виде моментального снимка.

Запустите команду Обновить-База данных в консоли диспетчера пакетов. Это применит миграцию InitialCreate в базу данных. Поскольку фактическая миграция не содержит никаких изменений, она просто добавит строку в таблицу __MigrationsHistory, указав, что эта миграция уже применена.

Здесь вы можете получить более подробную информацию: https://msdn.microsoft.com/en-us/library/dn579398(v=vs.113).aspx

Ответ 10

Эта ошибка также может произойти, если у вас есть записи-сироты в дочерней таблице. Очистка базы данных должна решить проблему.