Что вызывает оператор INSERT, конфликтующий с ограничением FOREIGN KEY?
Этот код работал для меня раньше, но я больше не уверен, что стало причиной этой ошибки. Мое единственное предположение состоит в том, что когда я пытаюсь создать Player, данные о команде отправляются обратно в таблицу Team и пытаются их дублировать, но, поскольку TeamId уникален, отсюда и возникает эта ошибка.
ошибка
Оператор INSERT конфликтовал с ограничением FOREIGN KEY "FK_dbo.Players_dbo.Teams_TeamId". Конфликт произошел в базе данных "Web", таблице "dbo.Teams", столбце "TeamId". Заявление было прекращено.
игрок
public class Player
{
...
...
[HiddenInput(DisplayValue = false)]
[ForeignKey("Team")]
public int TeamId { get; set; }
public virtual Team Team { get; set; }
...
}
команда
public class Team
{
[Key]
[HiddenInput(DisplayValue = false)]
public int TeamId { get; set; }
....
public virtual ICollection<Player> Players { get; set; }
}
контроллер
//
// GET: /Player/
[HttpGet]
public ActionResult Create()
{
PopulateTeamsDropDownList();
return View();
}
//
// POST: /Player/
[HttpPost]
public ActionResult Create(Player model)
{
if (ModelState.IsValid)
{
using (var db = new EfDb())
{
var userProfile = db.UserProfiles.Single(u => u.UserName == User.Identity.Name);
if (userProfile != null)
{
var player = new Player
{
UserProfile = userProfile,
....
....
};
db.Players.Add(player);
db.SaveChanges();
}
}
}
PopulateTeamsDropDownList(model.TeamId);
return View(model);
}
private void PopulateTeamsDropDownList(object selectedTeams = null)
{
var teamsQuery = from d in _iService.Teams
orderby d.Name
select d;
ViewBag.TeamID = new SelectList(teamsQuery, "TeamId", "Name", selectedTeams);
}
Посмотреть
<div class="editor-label">
@Html.LabelFor(model => model.TeamId, "Pick Your Team")
</div>
<div class="editor-field">
@Html.DropDownList("TeamId", String.Empty)
@Html.ValidationMessageFor(model => model.TeamId)
</div>
Как можно решить эту ошибку?
2 ответа
Вы должны попытаться завершить сущности, такие как команды, для вашего игрока. Особенно внешние ключи.
[HttpPost]
public ActionResult Create(Player model)
{
if (ModelState.IsValid)
{
using (var db = new EfDb())
{
//Since you have the username cached, you can check the local EF cache for the object before hitting the db.
//var userProfile = db.UserProfiles.Single(u => u.UserName == User.Identity.Name);
var userProfile = db.UserProfiles.Local.SingleOrDefault(u => u.UserName == User.Identity.Name)
?? db.UserProfiles.SingleOrDefault(u => u.UserName == User.Identity.Name);
if (userProfile != null)
{
var player = new Player
{
UserProfile = userProfile,
....
....
};
player.TeamId = 5;
db.Players.Add(player);
db.SaveChanges();
}
}
}
PopulateTeamsDropDownList(model.TeamId);
return View(model);
}
И убедитесь, что выпадающий список с вашей точки зрения является обязательным, и отправьте правильное значение в метод сообщения.
Причина этого в том, что вы вставляете запись в child
таблица, в которой значение ссылочного столбца еще не существует на parent
Таблица.
Рассмотрим следующий сценарий:
// PARENT TABLE
CREATE TABLE TableA
(
ID INT PRIMARY KEY
);
// CHILD TABLE
CREATE TABLE TableB
(
ID INT PRIMARY KEY,
TableA_ID INT,
CONSTRAINT tb_FK FOREIGN KEY (TableA_ID) REFERENCES TableA(ID)
);
// RECORDS OF PARENT TABLE
INSERT INTO TableA (ID) VALUES (1);
INSERT INTO TableA (ID) VALUES (2);
// RECORDS OF CHILD TABLE
INSERT INTO TableB (ID, TableA_ID) VALUES (1,1);
INSERT INTO TableB (ID, TableA_ID) VALUES (2,1);
INSERT INTO TableB (ID, TableA_ID) VALUES (3,2);
Если вы выполните приведенные выше операторы, это не приведет к сбою, поскольку ни один из них не нарушает правило ссылочной целостности.
Попробуйте выполнить следующее утверждение:
INSERT INTO TableB (ID, TableA_ID) VALUES (3,4);
Это не удается, потому что 4
которая является значением TableA_ID
быть вставленным не существует на Table1.ID
, Внешние ключи сохранили ссылочную целостность между записями.