我正在使用DbContext范围实现。基本上,这意味着我将继续使用环境DbContext方法。 More information
我简化了我的真实代码,并删除了与上下文流行为有关的所有逻辑...
using (var dbContextParentScope = ...)
{
DbContext parentContext = dbContextParentScope.Get<ApplicationContext>();
// that data will be in the DbContext cache
var accounts = parentContext.Accounts.ToList();
// this is always part of a separate method
using (var dbContextChildScope = ...)
{
DbContext childContext = dbContextChildScope.Get<ApplicationContext>();
var childAccounts = childContext.Accounts.ToList();
childAccounts.ForEach(a => a.DisplayName = "New name");
// after that operation parentContext data will be outdated
childContext.SaveChanges();
// this will reload updated entities in the parentContext
dbContextChildScope.RefreshEntitiesInParentScope(childAccounts);
}
// without Refresh operation we will work with outdated data
parentContext.SaveChanges();
}
这是例外情况,但是有时我们必须在重要交易之外保存重要信息。
实体框架有可能从DbContext中通过键获取记录:
if (((IObjectContextAdapter)childContext).ObjectContext.ObjectStateManager.TryGetObjectStateEntry(childAccounts[0], out ObjectStateEntry stateInChildScope))
{
var key = stateInChildScope.EntityKey;
if (((IObjectContextAdapter)parentContext).ObjectContext.ObjectStateManager.TryGetObjectStateEntry(key, out ObjectStateEntry stateInParentScope))
{
if (stateInParentScope.State == EntityState.Unchanged)
{
((IObjectContextAdapter)parentContext).ObjectContext.Refresh(RefreshMode.StoreWins, stateInParentScope.Entity);
}
}
}
EF Core没有此类功能,但具有'ChangeTracker'。它可以返回DbContext正在跟踪的条目:
parentContext.ChangeTracker.Entries().Where(w => w.State == EntityState.Unchanged).ToList()
但是我只想重新加载childContext中更新的记录。所以,如果我写这样的话:
var updatedEntry = childContext.Entry(childAccounts[0]);
parentContext.Entry(updatedEntry.Entity).Reload();
EF Core会像对待newEntry一样思考它,并且会抛出System.InvalidOperationException:
无法跟踪实体类型'Account'的实例,因为已经跟踪了另一个具有相同'{'EntityId'}关键字值的实例。附加现有实体时,请确保仅附加一个具有给定键值的实体实例。
我还发现了一些内部功能,但是我不想使用内部EF Core代码(只是这是使其正常工作的唯一方法),因为可以对其进行更改/删除:
var entityType = parentContext.Model.FindEntityType(typeof(TEntityType));
var key = entityType.FindPrimaryKey();
var stateManager = parentContext.GetDependencies().StateManager;
var keysDictionary = key.Properties.ToDictionary(x => x.Name, x => x.PropertyInfo.GetValue(childAccounts[0]));
var entry = stateManager.TryGetEntry(key, keysDictionary.Values.ToArray());
parentContext.Entry(entry.Entity).Reload();
有人知道如何从父上下文更新实体吗?
我希望得到您的帮助,因为我被困在这里,没有任何想法