简体   繁体   中英

Mapping a Dto to an object with id

I am making an app using the ASP.Net Boilerplate framework and in my Domain layer I have a simple "Boss" entity. Creating and retrieving these entities from the database works fine but I can't get the "Update" to work. When map my "UpdateBossDto" to a Boss object and try to update it I get this error:

$exception {System.InvalidOperationException: The instance of entity type 'Boss' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.

This error gets thrown in the BossManager class (I have removed the other methods for readability.

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

Here is my Update method in the BossAppService (i know getting the Id this way probably isn't great but right now I'm just desperate):

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

And my UpdateDto class which holds the same attributes as the Boss class itself:

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

How can I update the Boss object either with or without the Id? Any help would be greatly appreciated!

There's a number of issues here. First, the id should be coming from the request URL, since it uniquely identifies the resource that's being modified. This also saves you from having to do silly things like GetBossIdByName . Not only does that require an unnecessary query, but it's prone to error. The id is your key for a reason: it's unique. Names are not. You could have multiple bosses with the same name. Additionally, your name columns are likely not indexed, which means such a query is vastly more inefficient. Then, with your id, you should be querying the corresponding Boss out of your database, and mapping onto this instance, not creating a new instance. Finally, save that same instance back to the database. Then, you will have no issues.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM