IT评测·应用市场-qidao123.com
标题:
EFCore怎样更改跟踪状态
[打印本页]
作者:
熊熊出没
时间:
2024-11-20 19:46
标题:
EFCore怎样更改跟踪状态
这里简单介绍下几种修改实体大概导航的跟踪状态。
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>());
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/)
Powered by Discuz! X3.4