The instance of entity type 'Model' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked.
The instance of entity type 'Model' 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.
新增数据到数据库后再在同一个方法或请求更新某些字段报的错误,大概的意思就是=>
无法跟踪实体类型“Model”的实例,因为已经在跟踪具有相同键值{'Id'}的另一个实例。在附加现有实体时,请确保只附加一个具有给定键值的实体实例。考虑使用' dbcontexttoptionsbuilder。EnableSensitiveDataLogging'查看冲突的键值。
我的做法是既然同一个链接,那么我就重新弄一个连接出来,因为我这efcore组件封装了,取context有点麻烦。所以选择别的办法。
源代码如下,报错的地方就是@2这里的更新引发错误:
[HttpPost]
public async Task SaveData(PushMessageUpdateRequest data)
{
if (data == null)
throw new BusException($"{nameof(PushMessageUpdateRequest)} is null", ErrorCodeDefine.ParameterIsNull);
if (data.Id.IsNullOrEmpty())
{
InitEntity(data);
foreach (var content in data.Contents)
{
InitEntity(content);
}
await _pushMessageBusiness.AddDataAsync(data);
var res = await _soptBusiness.FirstOrDefault(x => x.BusinessCode == "tttt").GetCustomerPushInfo();
var groups = res.Where(x => x.Value != null).GroupBy(x => x.Value).ToDictionary(x => x.Key, y => y.Select(x => x.Key).ToList());
List<bool> pushedFlag = new List<bool> { };
foreach (var item in groups)
{
var pushContent = data.Contents.Where(x => x.Lang == item.Key.ToLower()).FirstOrDefault();
if (pushContent != null && pushContent.Content.IsNotNullOrEmpty())
{
if (data.PushTime == null)
{
var result = await _pushClient.SendPush(new Klickl.Push.Sdk.Model.SendPushRequest
{
Type = Klickl.Push.Sdk.Model.PushType.Google,
Ids = item.Value,
NoticeContent = pushContent?.Content,
Title = pushContent?.Title,
IsApnsProduction = false
});
pushedFlag.Add(result);
}
else
{
JobHelper.SetDelayJob(async () =>
{
var result = await _pushClient.SendPush(new Klickl.Push.Sdk.Model.SendPushRequest
{
Type = Klickl.Push.Sdk.Model.PushType.Google,
Ids = item.Value,
NoticeContent = pushContent?.Content,
Title = pushContent?.Title,
IsApnsProduction = false
});
pushedFlag.Add(result);
}, data.PushTime.Value.Subtract(DateTime.Now));
} }
} data.SuccessCount= pushedFlag.Where(x=>x==true).Count(); //@1
data.PushCount = groups.Count;
await _pushMessageBusiness.UpdateDataAsync(data); //@2
}
else
{
await _pushMessageBusiness.UpdateDataAsync(data);
}
}
首先想的是_pushMessageBusiness这个business重新构造一个,像这样@3新增的business,@4就是为了报错加上去的。测试发现还是报一样的错误。
private readonly IPushMessageBusiness _pushMessageBusiness; //@3
private readonly PushClient _pushClient;
private readonly IEnumerable<ISpotBusiness> _soptBusiness;
private readonly IAutoPushMessageBusiness _autoPushMessageBusiness;
private record SaveDataChangeEventArgs(string Id, int SucessCount, int PushCount);
private EventHandler<SaveDataChangeEventArgs> SaveDataChangeEventEventHandler; private readonly IPushMessageBusiness _updataPushMessageBusiness; @4
private IServiceScopeFactory _scopeFactory;
因为_pushMessageBusiness里面有idbaccessor,及数据库的底层链接,所以上面注入idbaccessor是没问题,可以把bug解决掉,但是这样取原始远不如获取business安全和稳定。

解决办法如下:
data.SuccessCount= pushedFlag.Where(x=>x==true).Count();
data.PushCount = groups.Count;
await _pushMessageBusiness.UpdateDataAsync(data);
上面代码最好独立出来,我通过事件来更新。
if (groups.Count > 0 && SaveDataChangeEventEventHandler != null)
SaveDataChangeEventEventHandler(this, new SaveDataChangeEventArgs(data.Id, pushedFlag.Where(x => x == true).Count(), groups.Count));
事件放到构造函数,主要是新注入了一个scope工厂,这个也是关键代码,生成了的business和原来是不一样的。代码如下:
public PushMessageController(IPushMessageBusiness pushMessageBusiness,
IPushClientFactory factory,
IEnumerable<ISpotBusiness> soptBusiness, IAutoPushMessageBusiness autoPushMessageBusiness,
IServiceScopeFactory scopeFactory)
{
_pushMessageBusiness = pushMessageBusiness;
_pushClient = factory.Create("ttttt");
_soptBusiness = soptBusiness;
_autoPushMessageBusiness = autoPushMessageBusiness;
_scopeFactory = scopeFactory;
SaveDataChangeEventEventHandler += (obj, args) =>
{
AsyncHelper.RunSync(async () =>
{
using(var scope = _scopeFactory.CreateAsyncScope())
{
var _bus = scope.ServiceProvider.GetRequiredService<IPushMessageBusiness>();
var entity = await _bus.GetEntityAsync(x => x.Id.Equals(args.Id));
if (entity == null) { return; }
entity.SuccessCount = args.SucessCount;
entity.PushCount = args.PushCount;
await _bus.UpdateAsync(entity);
} }); }; } private readonly IPushMessageBusiness _pushMessageBusiness;
private readonly PushClient _pushClient;
private readonly IEnumerable<ISpotBusiness> _soptBusiness;
private readonly IAutoPushMessageBusiness _autoPushMessageBusiness;
private record SaveDataChangeEventArgs(string Id, int SucessCount, int PushCount);
private EventHandler<SaveDataChangeEventArgs> SaveDataChangeEventEventHandler; private IServiceScopeFactory _scopeFactory;
public static class AsyncHelper
{
private static readonly TaskFactory _myTaskFactory =
new TaskFactory(CancellationToken.None, TaskCreationOptions.None, TaskContinuationOptions.None, TaskScheduler.Default); /// <summary>
/// 同步执行
/// </summary>
/// <param name="func">任务</param>
public static void RunSync(Func<Task> func)
{
_myTaskFactory.StartNew(func).Unwrap().ConfigureAwait(false).GetAwaiter().GetResult();
} /// <summary>
/// 同步执行
/// </summary>
/// <typeparam name="TResult">返回类型</typeparam>
/// <param name="func">任务</param>
/// <returns></returns>
public static TResult RunSync<TResult>(Func<Task<TResult>> func)
{
return _myTaskFactory.StartNew(func).Unwrap().ConfigureAwait(false).GetAwaiter().GetResult();
}
}
The instance of entity type 'Model' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked.的更多相关文章
- The instance of entity type 'xxxx' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked.
一.问题描述 问题:The instance of entity type 'xxxx' cannot be tracked because another instance with the sam ...
- The instance of entity type 'Menu' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked.
这里记录一个在使用.net core中ef core执行数据库操作时遇到的问题: 我在代码中使用DbContext下的Update方法准备将更改后的数据像这样步到数据库: _context.Menus ...
- EF 更新实体 The instance of entity type 'BabyEvent' cannot be tracked because another instance
加上AsNoTracking. 人不能两次踏入同一条河. 我 就踏入了.o(╥﹏╥)o
- The instance of entity type 'manager' 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 ent
最近在用ASP.NET CORE时遇到一些问题,现记录下: 出现上述错误,即在更新实体数据时出现的错误 services.AddDbContext<StoreContext>(c => ...
- The entity type XXX is not part of the model for the current context.
今天遇到了一个奇葩问题,虽然解决了,但还是一脸懵,先附赠一下别人的解决方案:https://www.cnblogs.com/zwjaaron/archive/2012/06/08/2541430.ht ...
- Entity Framework的核心 – EDM(Entity Data Model) 一
http://blog.csdn.net/wangyongxia921/article/details/42061695 一.EnityFramework EnityFramework的全程是ADO. ...
- EF,ADO.NET Entity Data Model简要的笔记
1. 新建一个项目,添加一个ADO.NET Entity Data Model的文件,此文件会生成所有的数据对象模型,如果是用vs2012生的话,在.Designer.cs里会出现“// Defaul ...
- Create Entity Data Model
http://www.entityframeworktutorial.net/EntityFramework5/create-dbcontext-in-entity-framework5.aspx 官 ...
- [转] EF cannot be tracked because another instance of this type with the same key is already being tracked
本文转自:http://stackoverflow.com/questions/6033638/an-object-with-the-same-key-already-exists-in-the-ob ...
- Entity Framework Tutorial Basics(5):Create Entity Data Model
Create Entity Data Model: Here, we are going to create an Entity Data Model (EDM) for SchoolDB datab ...
随机推荐
- KingbaseES V8R6运维案例之---sys_waldump解析wal日志
案例说明: wal日志文件记录了,事务操作的redo日志信息,由于wal日志文件是二进制文件,无法直接读取其文件内容.sys_waldump 可以解决这个问题,通过sys_waldump来解析wal ...
- HashMap的三种遍历方式--Java--小白必懂
初学Hash Map总感觉它的遍历很麻烦,其实看懂后总结一下就是:集合+泛型,没啥特别的 总结一下HashMap的三种遍历方法如下: 保证一看就会>>> 1 // 对HashMap的 ...
- python打包Windows.exe程序(pyinstaller)
python打包Windows.exe程序(pyinstaller) 基础命令 pip install pyinstaller 使用pip命令来安装pyinstaller模块. -F: pyinsta ...
- Unity最新一键清理Prefab中所有MissingComponent
因为老的API Properties.DeleteArrayElementAtIndex(propertyIndex);提示没权限修改, 而unity提供了新的API GameObjectUtil ...
- Vue入门笔记二
<Vue.js项目实战> 开发所需的包称为开发依赖,应该使用--save-dev标志进行安装 应用运行需要的直接依赖应该使用--save标志进行安装 模板 使用Pug Pug(以前称为Ja ...
- Refresh 重构(Refactor)
最近在闲暇之余重(第)温(一..次)此书, 首先能感受到的, 无论你是新程序员还是老程序员, 这本书都已经不具备太多的可读性了. 由于本书成书年代久远, 那个时候软件行业还不够发达, 面向对象还没有被 ...
- #随机#CF1198F GCD Groups 2
题目 将 \(n\) 个数分为两组,使得两组的GCD都为1,求具体的分组情况 分析 考虑直接打乱 \(n\) 个数,如果能使第一组GCD减小就减小,否则丢到第二组, 由于打乱后出错的概率会减小,所以r ...
- 一种基于DeltaE(CIE 1976)的找色算法
// QuickFinder.cpp : 此文件包含 "main" 函数.程序执行将在此处开始并结束. // #include <iostream> #define _ ...
- K8s技术全景:架构、应用与优化
本文深入探讨了Kubernetes(K8s)的关键方面,包括其架构.容器编排.网络与存储管理.安全与合规.高可用性.灾难恢复以及监控与日志系统. 关注[TechLeadCloud],分享互联网架构.云 ...
- SQL 查询优化指南:SELECT、SELECT DISTINCT、WHERE 和 ORDER BY 详解
SELECT 关键字 SQL的SELECT语句用于从数据库中选择数据.SELECT语句的基本语法如下: SELECT column1, column2, ... FROM table_name; 其中 ...