首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何清除ObjectStateManager

如何清除ObjectStateManager
EN

Stack Overflow用户
提问于 2014-02-11 19:26:12
回答 3查看 2.1K关注 0票数 0

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

代码语言:javascript
复制
dbContext.ObjectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Unchanged);

其行为似乎是ObjectStateManager中的所有对象(添加的、修改的)都将状态更改为Unchanged,因此代码将将它们全部返回。有办法清理吗?

我需要这样做,因为我正在重用上下文,并为处于未更改状态的实体做一些事情,但是由于ObjectSateManager与未更改的实体一起增长和增长(因为它在SaveChanges之后将它们全部更改为不变),它一次又一次地为一个实体做相同的工作。

编辑:

为什么detach方法不适用于我:

假设您有两个类:

代码语言:javascript
复制
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传递了一个Nation,其中有些城市需要更新或插入。

让我们假设如下:

代码语言:javascript
复制
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中,所有这些对象都处于不变状态。(在SaveChanges调用之后)

我循环遍历它们并将状态设置为不变,这将导致每个城市都有Nation = nullNation.Cities being empty

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-02-12 15:18:14

我找到了一个“完美”的解决方案,它没有清除ObjectStateManger,而是忽略了所有以前附加的/处理过的实体。

代码语言:javascript
复制
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();
}
票数 0
EN

Stack Overflow用户

发布于 2014-02-11 20:25:22

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

代码语言:javascript
复制
dbContext.ObjectContext.Detach( entity );

另外,如果不需要附加实体,则可以使用AsNoTracking()扩展方法。它将在不跟踪的情况下执行查询:

代码语言:javascript
复制
var items = dbContext.Items.AsNoTracking().Where(...);
票数 0
EN

Stack Overflow用户

发布于 2014-02-11 21:51:54

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21711182

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档