将 Dto 映射到具有 id 的对象
Mapping a Dto to an object with id
我正在使用 ASP.Net 样板框架制作一个应用程序,在我的域层中我有一个简单的 "Boss" 实体。从数据库中创建和检索这些实体工作正常,但我无法让 "Update" 工作。将我的 "UpdateBossDto" 映射到 Boss 对象并尝试更新它时,出现此错误:
$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.
在 BossManager 中抛出此错误 class(为了便于阅读,我删除了其他方法。
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 中的更新方法(我知道以这种方式获取 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 class,它拥有与 Boss class 本身相同的属性:
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 对象?任何帮助将不胜感激!
这里有很多问题。首先,id 应该来自请求 URL,因为它唯一标识正在修改的资源。这也使您不必做 GetBossIdByName
等愚蠢的事情。这不仅需要不必要的查询,而且容易出错。 id 是您的密钥是有原因的:它是独一无二的。名字不是。你可以有多个同名的老板。此外,您的姓名列可能没有索引,这意味着这样的查询效率要低得多。然后,使用您的 ID,您应该从数据库中查询相应的 Boss
,并将 映射到 此实例,而不是创建新实例。最后,将同一个实例保存回数据库。那么,你就没有问题了。
我正在使用 ASP.Net 样板框架制作一个应用程序,在我的域层中我有一个简单的 "Boss" 实体。从数据库中创建和检索这些实体工作正常,但我无法让 "Update" 工作。将我的 "UpdateBossDto" 映射到 Boss 对象并尝试更新它时,出现此错误:
$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.
在 BossManager 中抛出此错误 class(为了便于阅读,我删除了其他方法。
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 中的更新方法(我知道以这种方式获取 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 class,它拥有与 Boss class 本身相同的属性:
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 对象?任何帮助将不胜感激!
这里有很多问题。首先,id 应该来自请求 URL,因为它唯一标识正在修改的资源。这也使您不必做 GetBossIdByName
等愚蠢的事情。这不仅需要不必要的查询,而且容易出错。 id 是您的密钥是有原因的:它是独一无二的。名字不是。你可以有多个同名的老板。此外,您的姓名列可能没有索引,这意味着这样的查询效率要低得多。然后,使用您的 ID,您应该从数据库中查询相应的 Boss
,并将 映射到 此实例,而不是创建新实例。最后,将同一个实例保存回数据库。那么,你就没有问题了。