【发布时间】:2020-05-22 02:52:30
【问题描述】:
我有一个用于 .net core 2.1 的 Web 应用程序的微服务 API,但我总是遇到这个问题。 在我的服务层中,我尝试从存储库中读取一个对象。如果数据库中不存在这样的记录,我从头开始创建并插入它。
ConfigKeyDto configKey = await _configKeyRepository.GetByKey("LAST_DEMO_ACCOUNT_ID");
if (configKey == null)
{
configKey = GetConfigKey();
await _configKeyRepository.InsertConfigKey(configKey);
}
我做了一些处理,更新了 dto 的值,然后我尝试更新它,像这样
await _configKeyRepository.UpdateConfigKey(configKey);
我最终得到了臭名昭著的“无法跟踪实体类型 'ConfigKey' 的实例,因为已经在跟踪另一个具有相同键值的 'Id' 实例”。 以下是我的存储库代码:
public async Task<bool> InsertConfigKey(ConfigKeyDto configKey)
{
ConfigKey configKeyEnt = _mapper.Map<ConfigKey>(configKey);
configKeyEnt.Active = true;
configKeyEnt.CreateAt = System.DateTime.Now;
_context.Add<ConfigKey>(configKeyEnt);
await _context.SaveChangesAsync();
return true;
}
public async Task<bool> UpdateConfigKey(ConfigKeyDto configKey)
{
ConfigKey configKeyEnt = await _context.ConfigKeys.FirstOrDefaultAsync(x => x.Key == configKey.Key);
_context.Entry(configKeyEnt).State = EntityState.Modified;
_context.Entry(configKeyEnt).CurrentValues.SetValues(configKey);
await _context.SaveChangesAsync();
return true;
}
每当我必须在方法中读取/插入实体,然后再对其进行更新时,我都曾多次偶然发现这一点。什么是正确的方法来做到这一点而不诉诸杂物(比如处理上下文,或者直接使用我不喜欢的存储库层之外的数据库实体,所以我使用自动映射器)?
提前致谢
更新
我把它放在我所有的存储库方法中
_context.Entry<ConfigKey>(obj).State = EntityState.Detached;
成功了
【问题讨论】:
-
处理上下文只是一个杂项。您说这表明您有长期存在的上下文实例,这违反了所有建议。
-
我们使用作用域数据库上下文,它的存在时间与来自前端的 API 端点调用一样长。我一直都是这样工作的,但是每次涉及到选择/插入和更新时,我都会明白这一点。
标签: .net-core entity-framework-core