如何清理Entity Framework对象上下文?

Dan*_*ner 45 c# entity-framework

我正在向对象上下文添加几个实体.

try
{
    forach (var document in documents)
    {
        this.Validate(document); // May throw a ValidationException.

        this.objectContext.AddToDocuments(document);
    }

    this.objectContext.SaveChanges();
}
catch
{
    // How to clean-up the object context here?

    throw;
}
Run Code Online (Sandbox Code Playgroud)

如果某些文档通过了验证而一个文档失败,则所有通过验证的文档仍会添加到对象上下文中.我必须清理对象上下文,因为它可能会被重用,并且可能发生以下情况.

var documentA = new Document { Id = 1, Data = "ValidData" };
var documentB = new Document { Id = 2, Data = "InvalidData" };
var documentC = new Document { Id = 3, Data = "ValidData" };

try
{
    // Adding document B will cause a ValidationException but only
    // after document A is added to the object context.
    this.DocumentStore.AddDocuments(new[] { documentA, documentB, documentC });
}
catch (ValidationException)
{
}

// Try again without the invalid document B. This causes an exception because
// of a duplicate primary key - document A with id 1 is added a second time.
this.DocumentStore.AddDocuments(new[] { documentA, documentC });
Run Code Online (Sandbox Code Playgroud)

这将再次将文档A添加到对象上下文中,因此SaveChanges()会因为重复的主键而引发异常.

所以我必须在验证错误的情况下删除所有已添加的文档.我当然可以先执行验证,只有在成功验证后才添加所有文档,但遗憾的是这并不能解决整个问题 - 如果SaveChanges()失败,所有文档仍然保持添加但未保存.

我试图分离返回的所有对象

 this.objectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Added)
Run Code Online (Sandbox Code Playgroud)

但我得到一个例外,说明该对象没有附加.那么如何摆脱所有已添加但未保存的对象?

Gar*_*ish 43

Daniel的回答对我有用,但是EntityFramework API在版本6+中有所不同.这是我添加到自定义存储库容器的方法,它将从DbContext的ChangeTracker中分离所有实体:

    /// <summary>
    /// Detaches all of the DbEntityEntry objects that have been added to the ChangeTracker.
    /// </summary>
    public void DetachAll() {

        foreach (DbEntityEntry dbEntityEntry in this.Context.ChangeTracker.Entries().ToArray()) {

            if (dbEntityEntry.Entity != null) {
                dbEntityEntry.State = EntityState.Detached;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)


Dan*_*ner 38

这只是一个微不足道的错误,但我将在这里留下问题 - 也许它有助于其他人.

我有以下内容

var objectStateEntries = this.objectContext
                             .ObjectStateManager
                             .GetObjectStateEntries(EntityState.Added);

foreach (var objectStateEntry in objectStateEntries)
{
    this.objectContext.Detach(objectStateEntry);
}
Run Code Online (Sandbox Code Playgroud)

虽然我想要以下

foreach (var objectStateEntry in objectStateEntries)
{
    this.objectContext.Detach(objectStateEntry.Entity);
}
Run Code Online (Sandbox Code Playgroud)

而且看不到它.

  • 另外,可以使用按位标志来执行var objectStateEntries = this._context.ObjectStateManager .GetObjectStateEntries(EntityState.Added | EntityState.Deleted | EntityState.Modified | EntityState.Unchanged); 分离所有附加的对象 (7认同)

小智 5

EF 5.0开始ChangeTracker.Clear(),它会清除所有跟踪实体的 DbContext。