Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何清除ObjectStateManager_C#_Entity Framework_Objectstatemanager - Fatal编程技术网

C# 如何清除ObjectStateManager

C# 如何清除ObjectStateManager,c#,entity-framework,objectstatemanager,C#,Entity Framework,Objectstatemanager,我想清除ObjectStateManager,以便在调用SaveChanges()之后在DbContext上,以下行不返回任何结果: dbContext.ObjectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Unchanged); 其行为似乎是ObjectStateManager中的所有对象(添加、修改)都将状态更改为未更改,因此代码将返回所有对象。有没有办法清除它 我需要这样做,因为我正在重用上下文并为状态不变的

我想清除ObjectStateManager,以便在调用
SaveChanges()之后
在DbContext上,以下行不返回任何结果:

dbContext.ObjectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Unchanged);
其行为似乎是ObjectStateManager中的所有对象(添加、修改)都将状态更改为
未更改
,因此代码将返回所有对象。有没有办法清除它

我需要这样做,因为我正在重用上下文并为状态不变的实体做一些事情,但是由于ObjectSateManager随着不变的实体不断增长(因为它在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; }
}
现在,在ObjectStateManager中,所有这些对象都处于未更改状态。(在SaveChanges调用之后)


然后我循环遍历它们并将状态设置为未更改,这将导致每个城市都有
Nation=null
Nation.Cities为空

ObjectContext
Detach
方法将其从对象上下文中删除:

dbContext.ObjectContext.Detach( entity );
此外,如果不需要附加实体,可以使用
AsNoTracking()
扩展方法。它将执行查询而不跟踪:

var items = dbContext.Items.AsNoTracking().Where(...);

您可以做的是使用分页。每N个对象创建一个新的
DbContext
,但所有对象都使用相同的连接和事务。

我找到了一个“完美”的解决方案,它不清除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();
}
private static int\uu lastProcessedIndex=0;
私有静态DbContext _oldContext=null;
public void DoYourMagic(DbContext上下文)
{
if(ReferenceEquals(context,_oldContext)==false)
{
_oldContext=上下文;
_lastProcessedIndex=0;
}
var objectContext=(上下文为IObjectContextAdapter);
var unchanged=objectContext.ObjectStateManager.GetObjectSateEntries(EntityState.unchanged).ToArray();
for(int i=_lastProcessedIndex;i
您应该尽可能少地打开上下文。在整个应用程序中共享/重用上下文是个坏主意。@MarcinJuraszek我正在执行一个导入方法,该方法调用每个元素的SaveChanges,因为我想立即获得每个结果的反馈,因为整个导入总共有10.000个实体要保存,我相信使用一个上下文,一个事务比尝试用1创建10000个上下文要好?完全回滚的Transaction。您需要分离的实体做什么?他们获救后,你就不再和他们合作了吗?@ivowiblo很遗憾,我仍然需要他们(这是我老板给我的应用程序要求的一部分,这迫使我做一些实体框架不友好的事情,但我已经找到了一个适合我的解决方案,请看我的答案。我尝试了分离方法,但遗憾的是,这也改变了相关的导航属性。还有其他想法吗?你对分离的意思是什么“更改相关的导航属性"?问题是它根本不可伸缩。你真的从数据库中加载了10k个对象而没有处理它们吗?这个数字可能会增加吗?是的,我正在加载这些对象,但不,这个数字没有增加,这是最大值,很少有这么大的对象-更有可能是大约3000个。@ivowiblo忘记了(a)xxxx,请参阅我之前的评论。sry。
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();
}