How can I reject all changes in a Linq to SQL's DataContext?

Viewed 25180

On Linq to SQL's DataContext I am able to call SubmitChanges() to submit all changes.

What I want is to somehow reject all changes in the datacontext and rollback all changes (preferable without going to the database).

Is this possible?

11 Answers

Why not discard the data context and simply replace it with a new instance?

In .net 3.0 use the db.GetChangeSet().Updates.Clear() for updated, db.GetChangeSet().Inserts.Clear() for new or db.GetChangeSet().Deletes.Clear() for deleted items.

In .net 3.5 and above the result of GetChangeSet() is now readonly, loop the collection in for or foreach and refresh every ChangeSet table like also macias wrote in his comment.

As Haacked said, just drop the data context.

You probably shouldn't keep the data context alive for a long time. They're designed to be used in a transactional manner (i.e. one data context per atomic work unit). If you keep a data context alive for a long time, you run a greater risk of generating a concurrency exception when you update a stale entity.

Calling Clear() on the Updates, Deletes and Inserts collection does not work.

GetOriginalEntityState() can be useful, but it only gives the IDs for foreign key relationships, not the actual entities so you're left with a detached object.

Here's an article that explains how to discard changes from the data context: http://graemehill.ca/discard-changes-in-linq-to-sql-datacontext

EDIT: Calling Refresh() will undo updates, but not deletes and inserts.

The Refresh will work, however you have to give the entities you want to reset.

For example

dataContext.Refresh(RefreshMode.OverwriteCurrentValues, someObject);

You can use the GetOriginalEntityState(..) to get the original values for the objects e.g. Customers using the old cached values.

You can also iterate through the changes e.g. updates and refresh the specific objects only and not the entire tables because the performance penalty will be high.

foreach (Customer c in MyDBContext.GetChangeSet().Updates)
        {
            MyDBContext.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, c);
        }

this will revert the changes using persisted data in the database.

Another solution is to dump the datacontext you use, using Dispose().

In any case it is a good practice to override the Insert and Remove methods in the collection of e.g. Customers you use and add e.g. an InsertOnSubmit() call. This will resolve your issue with pending Insertions and Deletions.

//This works for me, 13 years later using Dotnet (Core) 6:

dbContext.ChangeTracker.Clear();

Related