C# 是什么导致INSERT语句与外键约束冲突?

C# 是什么导致INSERT语句与外键约束冲突?,c#,asp.net-mvc-4,visual-studio-2012,ef-code-first,entity-framework-ctp5,C#,Asp.net Mvc 4,Visual Studio 2012,Ef Code First,Entity Framework Ctp5,这段代码以前对我有用,但我不确定是什么导致了这个错误。我唯一的猜测是,当我尝试创建一个玩家时,团队数据被发送回团队表,并试图复制,但由于TeamId是唯一的,因此出现了此错误 错误 public class Player { ... ... [HiddenInput(DisplayValue = false)] [ForeignKey("Team")] public int TeamId { get; set; } public

这段代码以前对我有用,但我不确定是什么导致了这个错误。我唯一的猜测是,当我尝试创建一个玩家时,团队数据被发送回团队表,并试图复制,但由于TeamId是唯一的,因此出现了此错误

错误

public class Player
{
    ...
    ...

    [HiddenInput(DisplayValue = false)]
    [ForeignKey("Team")]
    public int TeamId { get; set; }        

    public virtual Team Team { 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);
    }
INSERT语句与外键约束“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; }

    ...
}
//
    // 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>

@LabelFor(model=>model.TeamId,“选择您的团队”)
@Html.DropDownList(“TeamId”,String.Empty)
@Html.ValidationMessageFor(model=>model.TeamId)

如何解决此错误?

您应该尝试为您的玩家实体完成实体,如团队。尤其是外键

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

并确保视图中的下拉列表是必需的,并将正确的值发送到post方法。

这背后的原因是当您在
子表
中插入一条记录时,引用列的值在
父表
中尚不存在

考虑以下场景:

// 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);

它失败,因为要插入的
TableA\u ID
的值
4
Table1.ID
上不存在。外键保留了记录之间的引用完整性。

谢谢,伙计,结果是
player.TeamId=5是关键。我不知道我怎么会错过这个。@Floradu88您只是为了检查播放器是否存在而对数据库进行了不必要的访问。如果在代码中检查Id,您已经知道它存在。你应该更新它,因为它会导致糟糕的性能实践。@FeistyMango这是我的原始代码,我之所以要访问数据库是因为
Player
UserProfile
的孩子,我需要
UserId
用于
Player
@KomengeMwandila,因为我看到了更新的版本。但是,我肯定会添加一个关于缓存用户配置文件的内容,因为它会导致同样不必要的性能损失。@KomengeMwandila在这种情况下,EF已经在缓存用户配置文件了。您只需跟踪Id,然后就可以从EF的本地缓存中检索它。我相信这也会起作用,但由于
code First
,我很久没有执行纯
SQL
。请尝试对特定任务使用seed方法:P