是什么原因INSERT语句与FOREIGN KEY约束冲突?

时间:2013-03-23 07:06:03

标签: c# asp.net-mvc-4 visual-studio-2012 ef-code-first entity-framework-ctp5

此代码以前对我有用,但我不确定是什么导致了这个错误。我唯一的猜测是,当我尝试创建一个播放器时,团队数据将被发送回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 个答案:

答案 0 :(得分:10)

这背后的原因是当您在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在{{1}}上不存在。外键保留了记录之间的参照完整性。

答案 1 :(得分:8)

您应该尝试为玩家实体完成团队等实体。特别是外键。

[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);
    }

并确保您视图中的Dropdown是必需的,并将正确的值发送到post方法。

相关问题