将Dto映射到ID为的对象

时间:2019-02-08 16:32:54

标签: c# asp.net-core aspnetboilerplate

我正在使用ASP.Net Boilerplate框架制作应用程序,并且在我的域层中,我有一个简单的“老板”实体。从数据库创建和检索这些实体工作正常,但我无法使“更新”正常工作。将我的“ UpdateBossDto”映射到Boss对象并尝试对其进行更新时,出现此错误:

  

$ exception {System.InvalidOperationException:实体的实例   无法跟踪类型“老板”,因为另一个具有相同实例   {'Id'}的键值已被跟踪。附加现有时   实体,请确保只有一个具有给定键值的实体实例   被附上。考虑使用   'DbContextOptionsBuilder.EnableSensitiveDataLogging'以查看   冲突的键值。

此错误在BossManager类中引发(为了便于阅读,我删除了其他方法。

public class BossManager : DomainService, IBossManager
{
    private readonly IRepository<Boss> _repositoryBoss;         
    public BossManager(IRepository<Boss> repositoryBoss)
    {
        _repositoryBoss = repositoryBoss;
    }   
    public void Update(Boss entity)
    {
        _repositoryBoss.UpdateAsync(entity);
    } 
}

这是BossAppService中的Update方法(我知道以这种方式获取ID可能不太好,但现在我很不顾一切):

public void Update(UpdateBossDto updatedBoss)
{
    var boss = new Boss();
    updatedBoss.Id = _bossManager.GetBossIdByName(updatedBoss.Name);
    boss = ObjectMapper.Map<Boss>(updatedBoss);
    _bossManager.Update(boss);
}

还有我的UpdateDto类,它具有与Boss类本身相同的属性:

public class UpdateBossDto
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Hp { get; set; }
    public int CombatLvl { get; set; }
    public int MaxHit { get; set; }
    public string AttackStyle { get; set; }
    public string Weakness { get; set; }
    public string ImageUrl { get; set; }
}

无论有没有ID,如何更新Boss对象?任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

这里有很多问题。首先,该ID应该来自请求URL,因为它唯一地标识了正在修改的资源。这也使您不必进行诸如GetBossIdByName之类的愚蠢的事情。这不仅需要不必要的查询,而且容易出错。 id是您的密钥,这是有原因的:它是唯一的。名字不是。您可以有多个同名老板。此外,您的名称列可能未编入索引,这意味着这种查询的效率大大降低。然后,使用您的ID,您应该从数据库中查询相应的Boss,并将该实例映射到该实例,而不是创建新实例。最后,将该同一个实例保存回数据库。这样,您将没有问题。