How may an Entity Framework object context be cleaned up?

c# entity-framework

Question

I'm expanding an object context with a number of entities.

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;
}

All documents that passed the validation are still added to the object context even if some of the documents pass and one fails. The object context has to be cleaned up since it could be reused and the following might occur.

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 });

As a result, document A will once again be added to the object context.SaveChanges() will raise an error due to a main key duplication.

In the event of a validation mistake, I must thus delete every document that has previously been uploaded. Of course, I could verify first and only upload all papers after they have been properly verified, but regrettably, this does not completely fix the issue. If onlySaveChanges() fails, all additional documents are still shown but not saved.

I made an effort to remove each item returned by

 this.objectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Added)

However, I'm receiving a warning that the item isn't associated. So, how do I delete every item I added but didn't save?

1
45
3/17/2010 9:17:01 PM

Accepted Answer

Even though it was just a little problem, I'm going to keep the query up in case it helps someone else.

What I had was this

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

foreach (var objectStateEntry in objectStateEntries)
{
    this.objectContext.Detach(objectStateEntry);
}

yet I wished for the following

foreach (var objectStateEntry in objectStateEntries)
{
    this.objectContext.Detach(objectStateEntry.Entity);
}

and failed to see it.

38
3/17/2010 9:31:22 PM

Popular Answer

Although the EntityFramework API is changed in version 6+, Daniel's response worked for me. The following function I included in my personal repository container will disconnect all entities from the DbContext's 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;
            }
        }
    }


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow