10

此代碼已爲我工作過,但我不知道什麼一直導致此錯誤。我唯一的猜測是,當我嘗試創建一個播放器時,團隊數據被髮送回Team Table並嘗試複製,但是由於TeamId是唯一的,所以這個錯誤。什麼原因INSERT語句與FOREIGN KEY約束衝突?

錯誤

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

    ... 
} 

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> 

怎樣才能解決這個問題?

回答

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

並確保您的視圖中的下拉菜單是必需的,並向post方法發送正確的值。

+0

感謝哥們,原來'player.TeamId = 5;'是關鍵。我不知道我錯過了這個。 – Komengem 2013-03-23 07:15:12

+1

@ Floradu88爲了檢查播放器是否存在,您正在進行不必要的數據庫訪問。如果您在代碼中檢查ID,您已經知道它存在。你應該更新它,因爲它會導致糟糕的性能實踐。 – 2013-03-23 07:17:04

+0

@FeistyMango這是我的原始代碼,之所以我採取這次旅行到數據庫是因爲'Player'是'UserProfile'的孩子,我需要'UserId'作爲'Player' – Komengem 2013-03-23 07:19:02

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要被插在Table1.ID不存在的TableA_ID值。外鍵保留了記錄之間的參照完整性。

+0

我相信這也會起作用,但自從Code First之後,我很久沒有執行普通的'SQL'了。 – Komengem 2013-03-23 07:24:16

+0

嘗試使用種子方法進行特定任務:P – 2013-03-23 07:32:37