我想清除ObjectStateManager,以便在DbContext上调用SaveChanges();
之后,以下行不返回任何结果:
dbContext.ObjectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Unchanged);
行为似乎是ObjectStateManager中的所有对象(已添加,已修改)都将状态更改为Unchanged
,因此代码将全部返回。有没有办法清除它?
我需要这个,因为我正在重用上下文并为具有Unchanged状态的实体做一些事情,但是因为ObjectSateManager随着Unchanged Entities的增长而增长(因为它在SaveChanges之后将它们全部更改为Unchanged)它为一个实现同样的工作实体一遍又一遍。
修改
为什么分离方法对我不起作用:
让我们假设你有两个班级:
public class Nation
{
public string Name { get; set; }
public ICollection<City> Cities { get; set; }
}
public class City
{
public string Name { get; set; }
public Nation Nation { get; set; }
}
现在我已经向SaveChanges传递了一个国家项目,其中包含一些需要更新或插入的城市。
让我们假设以下内容:
var canada = new Nation()
{
Name = "Canada",
}
canada.Cities = new City[]
{
new City(){ Name = "Ottawa", Nation = canada, },
new City(){ Name = "Edmonton", Nation = canada, },
new City(){ Name = "Victoria", Nation = canada, },
new City(){ Name = "Torronto", Nation = canada, }
},
}
现在,我的ObjectStateManager中的所有这些对象都处于Unchanged状态。 (在SaveChanges调用之后)
我循环遍历它们并将状态设置为不变,这导致每个城市都有Nation = null
和Nation.Cities being empty
。
答案 0 :(得分:0)
Detach
的{{1}}方法会将其从对象上下文中删除:
ObjectContext
此外,如果您不需要附加实体,则可以使用dbContext.ObjectContext.Detach( entity );
扩展方法。它将执行查询而不跟踪:
AsNoTracking()
答案 1 :(得分:0)
您可以做的是使用分页。每N个对象创建一个新的DbContext
个新对象,但所有对象都使用相同的连接和事务。
答案 2 :(得分:0)
我找到了一个对我“完美”有效的解决方案,它不会清除ObjectStateManager但忽略所有以前连接/处理的实体。
private static int __lastProcessedIndex = 0;
private static DbContext _oldContext = null;
public void DoYourMagic(DbContext context)
{
if (ReferenceEquals(context, _oldContext) == false)
{
_oldContext = context;
_lastProcessedIndex = 0;
}
var objectContext = (context as IObjectContextAdapter).ObjectContext;
var unchanged = objectContext.ObjectStateManager.GetObjectSateEntires(EntityState.Unchanged).ToArray();
for (int i = _lastProcessedIndex; i < unchanged.Length; i++)
{
//do your magic with unchanged entities...
}
context.SaveChanges();
//Now all entries in objectstatemanager are in state Unchanged
//I am setting the index to the Count() - 1
//So that my next call of the method "DoYourMagic" starts the for with this index
//This will than ignore all the previously attached ones
_lastProcessedIndex = objectContext.ObjectStateManager.GetObjectSateEntires(EntityState.Unchanged).Count();
}