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");
}
Ответы
Ответ 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
Эта ошибка также может произойти, если у вас есть записи-сироты в дочерней таблице. Очистка базы данных должна решить проблему.