0

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

dbContext.ObjectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Unchanged);

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

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

编辑:

为什么分离方法对我不起作用:

假设您有 2 个类:

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 中所有这些对象都处于未更改状态。(在 SaveChanges 调用之后)

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

4

3 回答 3

0

I found a solution that works for me "perfectly", it doesnt Clear the ObjectStateManger but ignores all the previously attached/processed entities.

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();
}
于 2014-02-12T15:18:14.193 回答
0

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

dbContext.ObjectContext.Detach( entity );

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

var items = dbContext.Items.AsNoTracking().Where(...);
于 2014-02-11T20:25:22.370 回答
0

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

于 2014-02-11T21:51:54.427 回答