首页 > 其他分享 >EFCore如何更改跟踪状态

EFCore如何更改跟踪状态

时间:2024-11-20 15:41:01浏览次数:1  
标签:obj 更改 ctx IDbContextDependencies entity StateManager 跟踪 EFCore var

这里简单介绍下几种修改实体或者导航的跟踪状态。

1. 直接修改实体

对已在DbContext中跟踪的实体,直接操作,如给字段赋值、给导航属性赋值或者添加删除等
对未在DbContext中跟踪的实体,调用DbContext的Add、Update、Remove等方法,对已跟踪的实体也有效
需要注意所有添加的实体都需要调用DbContext.Add方法

2. 利用IStateManager.ChangingState(InternalEntityEntry,EntityState)

这个很简单,关键的是如何获得InternalEntityEntry,方法是调用IStateManager.TryGetEntry方法返回获得,该方法多个重载,主要都是传实体或者主键。

Type type = ....// 实体类型
DbContext ctx=...
var entityType = ctx.Model.FindEntityType(type);
var key = entityType.FindPrimaryKey();
var internalEntityEntry = ((IDbContextDependencies)ctx).StateManager.TryGetEntry(key,主键值);
((IDbContextDependencies)ctx).StateManager.ChangingState(internalEntityEntry,EntityState.Modified);

传主键同样可以获得隐式定义的ISkipNavigation的InternalEntityEntry,请看5中示例。

3. 利用集合导航属性的INavigationBase.GetCollectionAccessor()

INavigationBase.GetCollectionAccessor()返回IClrCollectionAccessor类型,使用它的Add和Remove方法操作集合,但是这里只针对已经在DbContext跟踪的才有效果,否则请参考5中的做法。

4. 利用IStateManager.InternalEntityEntryNotifier.NavigationCollectionChanged

对于已经跟踪的实体或导航,还可以NavigationCollectionChanged方法更改添加或者删除,主要是针对集合导航属性。

Object entity=...//实体对象,假设它有个集合导航属性:Data
var navigationEntry = ctx.Entry(entity).Navigation("Data");
var obj = entity.Data.First();//假设不为空
//将集合导航属性Data中obj修改成添加状态(EntityState.Added)
((IDbContextDependencies)ctx).StateManager.InternalEntityEntryNotifier.NavigationCollectionChanged(ctx.Entry(entity).GetInfrastructure(), navigationEntry.Metadata, new[] { obj }, Array.Empty<object>());
//将集合导航属性Data中obj修改成删除状态(EntityState.Deleted)
((IDbContextDependencies)ctx).StateManager.InternalEntityEntryNotifier.NavigationCollectionChanged(ctx.Entry(entity).GetInfrastructure(), navigationEntry.Metadata, Array.Empty<object>(), new[] { obj });

5. ISkipNavigation的状态修改

在第4点中,对于ISkipNavigation,无法修改导航的状态为EntityState.Unchanged,那么这里可以这么做。

if (navigationEntry.Metadata is ISkipNavigation skipNavigation)
{
    var targetEntry = ((IDbContextDependencies)ctx).StateManager.GetOrCreateEntry(obj, navigationEntry.Metadata.TargetEntityType);
    var key = skipNavigation.JoinEntityType.FindPrimaryKey();
    var a = ctx.Entry(entity).GetInfrastructure()[skipNavigation.ForeignKey.PrincipalKey.Properties[0]];
    var b = targetEntry[skipNavigation.Inverse.ForeignKey.PrincipalKey.Properties[0]];
    var joinEntry = ((IDbContextDependencies)ctx).StateManager.TryGetEntry(key, new[] { a, b });
    joinEntry.SetEntityState(EntityState.Unchanged);//也可以用IStateManager.ChangingState
}

如果ISkipNavigation还是未跟踪的,那么上面的代码joinEntry获得的是null,可以在上面代码之前加这两行就可以了。

((IDbContextDependencies)ctx).StateManager.CompleteAttachGraph()
((IDbContextDependencies)ctx).StateManager.InternalEntityEntryNotifier.NavigationCollectionChanged(ctx.Entry(entity).GetInfrastructure(), navigationEntry.Metadata, new[] { obj }, Array.Empty<object>());

标签:obj,更改,ctx,IDbContextDependencies,entity,StateManager,跟踪,EFCore,var
From: https://www.cnblogs.com/pains/p/18558548

相关文章

  • 【MATLAB代码】基于IMM(Interacting Multiple Model)算法的目标跟踪,所用模型:CV、CA、CT
    文章目录3个模型的IMM(代码简介)源代码运行结果代码介绍总结3个模型的IMM(代码简介)本MATLAB代码实现了基于IMM(InteractingMultipleModel)算法的目标跟踪。它使用三种不同的运动模型(匀速直线运动、左转弯和右转弯)来预测目标的位置,并通过卡尔曼滤波进行状态估计。源代......
  • OpenCV-Python Shi-Tomasi 角点检测 & 适合于跟踪的图像特征
    原理上一节我们学习了Harris角点检测,后来1994年,J.Shi和C.Tomasi在他们的文章《Good_Features_to_Track》中对这个算法做了一个小小的修改,并得到了更好的结果。我们知道Harris角点检测的打分公式为:R=\lambda_1\lambda_2-k(\lambda_1+\lambda_2)^2但Shi-......
  • 理解进程调度时机跟踪分析进程调度与进程切换的过程
    张晓攀+原创作品转载请注明出处+《Linux内核分析》MOOC课程https://mooc.study.163.com/course/1000029000实验八——理解进程调度时机跟踪分析进程调度与进程切换的过程一、理解Linux系统中进程调度的时机在Linux内核中,schedule()函数是核心的进程调度机制。它的主要作用是......
  • Android 8.0 更换TTS为Google TTS , TTS播报出来是女声,更改为男生
    diff--gita/frameworks/base/core/java/android/speech/tts/TextToSpeech.javab/frameworks/base/core/java/android/speech/tts/TextToSpeech.javaindex763ea2ca38…2ec9f737b0100755—a/frameworks/base/core/java/android/speech/tts/TextToSpeech.java+++b/fr......
  • 自动化测试工具Ranorex Studio(三十五)-跟踪界面元素
    对于你要测试的应用程序,你可以通过RanorexSpy的元素树手动的引导或使用元素跟踪来识别界面元素。RanorexSpy有两种方法来跟踪界面元素:•   使用TRACK按钮•   即时跟踪使用跟踪按钮点击“TRACK”按钮开始跟踪界面元素。移动鼠标到一个特定的控件(例如:按钮或文本框)......
  • 2024/11/15日 日志 关于 会话跟踪技术--- Cookie & Session
    会话跟踪技术--·会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。--在一次会话中可以包含多次请求和响应--·会话跟踪:一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,--以便在同一次会话的多次请求间共享数据--·......
  • 在 Windows 中,RDP(远程桌面协议)默认使用 3389 端口。如果你想通过 PowerShell 更改此端
    在Windows中,RDP(远程桌面协议)默认使用3389端口。如果你想通过PowerShell更改此端口为10010,你需要修改注册表设置并重启远程桌面服务。以下是使用PowerShell更改RDP端口为10010的步骤:步骤:以管理员身份运行PowerShell。执行以下命令修改注册表,修改RDP端口设置:p......
  • ABAP开发学习——ST05 ABAP SQL跟踪工具
    操作步骤第一步使用ST05之前,将要查的程序停留想要看的操作的前一步,这里想看到取数操作,所以停留在选择界面第二步进入ST05选择SQLTrace然后激活第三步去执行程序第四步ST05取消激活第五步查看操作选完时间直接执行......
  • Springboot毕业生信息跟踪系统的设计与实现89ktp(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表学生,招聘信息,招聘申请,职业测评,就业问答,测评结果,问答结果,跟踪调查,就业报道,档案信息开题报告内容一、研究背景随着高等教育的普及和毕业生数量的增加,如......
  • Tomcat 容器的时区更改为中国
    要将Tomcat容器的时区更改为中国(通常为东八区,即Asia/Shanghai),可以按照以下步骤配置。方法一:修改catalina.sh或catalina.bat打开Tomcat的bin目录,找到启动脚本catalina.sh(Linux/Unix)或catalina.bat(Windows)。在启动脚本中找到JAVA_OPTS配置行,添加以下内容:JAVA_O......