10

Mã này đã làm việc cho tôi trước đây nhưng tôi không chắc chắn nữa điều gì đã gây ra lỗi này. Đoán duy nhất của tôi là khi tôi cố gắng tạo một Player, Team Data đang được gửi trở lại bảng Team và nó cố gắng lặp lại nhưng vì TeamId là duy nhất do đó lỗi này.Nguyên nhân Câu lệnh INSERT xung đột với ràng buộc KEY NGOẠI HỐI là gì?

Lỗi

Câu lệnh INSERT mâu thuẫn với các ràng buộc khoá ngoại "FK_dbo.Players_dbo.Teams_TeamId". Xung đột xảy ra trong cơ sở dữ liệu "Web", bảng "dbo.Teams", cột 'TeamId'. Các tuyên bố này đã bị chấm dứt.

chơi

public class Player 
{ 
    ... 
    ... 

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

    public virtual Team Team { get; set; } 

    ... 
} 

Đội

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

    .... 

    public virtual ICollection<Player> Players { get; set; } 
} 

khiển

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

Xem

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

Làm thế nào có thể giải quyết lỗi này?

Trả lời

8

Bạn nên cố gắng hoàn thành các thực thể như nhóm cho thực thể người chơi của mình. Đặc biệt là chìa khóa nước ngoài.

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

Và đảm bảo thả xuống từ chế độ xem của bạn là bắt buộc và gửi giá trị đúng cho phương thức bài đăng.

+0

Cảm ơn bạn thân, bật ra rằng 'player.TeamId = 5;' là khóa. Tôi không biết làm thế nào tôi bỏ lỡ điều này. – Komengem

+1

@ Floradu88 Bạn đang thực hiện một chuyến đi không cần thiết đến cơ sở dữ liệu chỉ để kiểm tra xem Người chơi có tồn tại hay không. Bạn đã biết nó tồn tại nếu bạn kiểm tra Mã trong mã. Bạn nên cập nhật điều này vì nó dẫn đến thực hành hiệu suất kém. –

+0

@FeistyMango Đó là mã ban đầu của tôi, lý do tại sao tôi đang thực hiện chuyến đi đó đến cơ sở dữ liệu là vì 'Trình phát' là con của 'UserProfile' và tôi cần' UserId' cho' Trình phát' – Komengem

10

Lý do đằng sau việc này là khi bạn chèn bản ghi vào bảng child mà giá trị của cột tham chiếu không tồn tại trên bảng parent.

Hãy xem xét kịch bản sau đây:

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

Nếu bạn thực hiện những điều khoản trên, nó sẽ không thất bại vì không ai trong số họ vi phạm các quy tắc toàn vẹn tham chiếu.

Hãy thử thực hiện các tuyên bố sau:

INSERT INTO TableB (ID, TableA_ID) VALUES (3,4); 

Nó thất bại vì 4 đó là giá trị của TableA_ID được chèn không tồn tại trên Table1.ID. Khóa ngoại được duy trì tính toàn vẹn tham chiếu giữa các bản ghi.

+0

Tôi chắc chắn điều này cũng sẽ làm việc nhưng kể từ 'Mã đầu tiên', tôi đã không thực hiện đồng bằng' SQL' trong một thời gian dài. – Komengem

+0

Hãy thử sử dụng phương pháp hạt giống cho nhiệm vụ cụ thể: P –