【问题标题】:Entity Framework: AutoMapper: ObjectStateManager exception thrown when setting EntityState.Modified on existing item实体框架:AutoMapper:在现有项目上设置 EntityState.Modified 时引发 ObjectStateManager 异常
【发布时间】:2014-08-30 23:18:04
【问题描述】:

我在尝试更新我的 Player 对象时遇到以下异常。

An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.

我正在抓取实体,将其自动映射到 DTO,在表单中对其进行编辑,将其发送回并在保存之前转换回 EF 对象。

public class Player
{
    [Key]
    public int PlayerId {get; set;}

    //visual only, not a foreign key
    public int PlayerCompetitionId {get;set;}

    public string FirstName {get; set;}
    public string LastName {get; set;}

    [Column("ClubId")]
    public int? CurrentClubId { get; set; }
    [ForeignKey("CurrentClubId")]
    public virtual Club CurrentClub { get; set; }
}

public class PlayerDTO
{
    public int PlayerId {get; set;}

    public virtual int PlayerCompetitionId {get;set;}

    public virtual string FirstName {get; set;}
    public virtual string LastName {get; set;}

    public virtual Club CurrentClub { get; set; }
}

public class Club
{
     public int ClubId {get; set;}
     public string Name {get; set;}
}

这是我的 AutoMapper 映射:-

AutoMapper.Mapper.CreateMap<Player, PlayerDTO>();
AutoMapper.Mapper.CreateMap<PlayerDTO, Player>()
            .ForMember(x => x.CurrentClubId, opt => opt.MapFrom(dto => (dto.CurrentClub.ClubId == 0) ? null : dto.CurrentClub.ClubId as int?))
            .ForMember(x => x.CurrentClub, opt => opt.Ignore());

当我保存 DTO 对象时,我可以看到映射看起来很好。 但是当我将 EntityState 设置为 modified 时,我得到了上述异常。

这是我的最终映射代码并保存。

public void SetModified(DTOPlayer updatedPlayer)
{
    Player player = AutoMapper.Mapper.Map<Player>(updatedPlayer);

    this.Entry(player).State = EntityState.Modified;
}

我的可为空的 int 属性有问题吗? 因为我有另一个 DTO 模型,当我做完全相同的事情时,它可以正确保存。

谢谢。

【问题讨论】:

  • 你能显示 this.Entry(player).State = EntityState.Modified;方法?
  • 即public DbEntityEntry Entry(object entity);来自实体框架。它在 DbContext 中。应该更明确地使用“base”而不是“this”。

标签: c# entity-framework automapper


【解决方案1】:

在您的代码中创建一个新的播放器对象。该方法正在尝试添加它并设置为已修改,但它已经存在。我认为您需要从上下文中获取玩家,然后将 DTO 的值映射到其中。在这种情况下,您甚至不需要设置为 modified - 它应该自动发生。

public void SetModified(DTOPlayer updatedPlayer)
{
    Player player = // however you get that particular player from the db context

    AutoMapper.Mapper.Map<DTOPlayer, Player>(updatedPlayer, player);
}

【讨论】:

  • 所以这行得通,但是现在我对我的其他模型如何与其他方法正常工作感到困惑。 (只是自动映射、SetModified 和保存)。我不必从上下文中获取原件。我认为因为主键相同,所以没问题。知道为什么会这样吗?
  • 是的,这也让我摸不着头脑。也许您将实体发送到尚不存在的其他方法,或者您的 PK 搞砸了或不存在。感谢您在记事本中进行的编辑 btw :)
  • 没问题。谢谢你的协助。在我选择这个作为选择的答案之前,我将做更多的研究并深入了解这个问题。
猜你喜欢
  • 1970-01-01
  • 2012-11-17
  • 1970-01-01
  • 2016-06-18
  • 1970-01-01
  • 2018-09-13
  • 1970-01-01
  • 1970-01-01
  • 2016-12-27
相关资源
最近更新 更多