实体框架 - "不能插入重复的对象"为儿童模型

时间:2016-01-18 11:05:04

标签: c# .net entity-framework

我确信有一个非常简单的解决方案。使用EntityFramework,给出这三个模型:

public class Player {
    public string Id {get; set;}
    public string Name {get; set;}
    public Team Team {get; set;}
}

public class Team {
    public string Id {get; set;}
    public string Name {get; set;}
}

public class Sponsor {
   public string Id {get; set;}
   public Player Representative {get; set;}
}

上下文中的相应集:

    public DbSet<Player> Players { get; set; }
    public DbSet<Team> Teams { get; set; }
    public DbSet<Sponsor> Sponsors { get; set; }

当团队已经存在时添加新玩家时会出现问题。

只有添加新播放器才能正常工作:

  // player is a new Player
  using (var db = new MyContext())
  {
       db.Players.AddOrUpdate(player);
       db.SaveChanges();
  }

但是尝试更改现有赞助商的代表属性失败:

using (var db = new MyContext())
{
     var sponsor = db.Sponsors.Single(s => s.Id == 1);
     sponsor.Representative = player;
     db.SaveChanges();
}

失败并显示错误:

{&#34;违反PRIMARY KEY约束&#39; PK_dbo.Teams&#39;。无法在对象&#39; dbo.Teams&#39;中插入重复的密钥。&#34;}

我不希望它复制团队条目。

2 个答案:

答案 0 :(得分:4)

这是由AddOrUpdate中的known bug引起的。解决方法是替换对EF实际跟踪的对象的player引用:

using (var db = new MyContext())
{
     db.Players.AddOrUpdate(player);
     db.SaveChanges();

     // Get the actually tracked player:
     player = db.Players.Local.Single(p => p.Id == player.Id);
}

在您当前的代码中,当您这样做时...

sponsor.Representative = player;

...... EF&#34;认为&#34;您正在添加新播放器,因为它无法跟踪player所指的对象。

答案 1 :(得分:0)

正如我们在您的错误中看到的那样,您尝试使用相同的 ID 添加多个Teams对象,这样您就会收到此错误,使主键自动增加您的问题将得到解决。