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

后端 未结 10 757
礼貌的吻别
礼貌的吻别 2020-11-27 18:57

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 a

相关标签:
10条回答
  • 2020-11-27 19:13

    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.

    0 讨论(0)
  • 2020-11-27 19:14

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

    0 讨论(0)
  • 2020-11-27 19:16
    public static class DataContextExtensions
    {
        /// <summary>
        ///     Discard all pending changes of current DataContext.
        ///     All un-submitted changes, including insert/delete/modify will lost.
        /// </summary>
        /// <param name="context"></param>
        public static void DiscardPendingChanges(this DataContext context)
        {
            context.RefreshPendingChanges(RefreshMode.OverwriteCurrentValues);
            ChangeSet changeSet = context.GetChangeSet();
            if (changeSet != null)
            {
                //Undo inserts
                foreach (object objToInsert in changeSet.Inserts)
                {
                    context.GetTable(objToInsert.GetType()).DeleteOnSubmit(objToInsert);
                }
                //Undo deletes
                foreach (object objToDelete in changeSet.Deletes)
                {
                    context.GetTable(objToDelete.GetType()).InsertOnSubmit(objToDelete);
                }
            }
        }
    
        /// <summary>
        ///     Refreshes all pending Delete/Update entity objects of current DataContext according to the specified mode.
        ///     Nothing will do on Pending Insert entity objects.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="refreshMode">A value that specifies how optimistic concurrency conflicts are handled.</param>
        public static void RefreshPendingChanges(this DataContext context, RefreshMode refreshMode)
        {
            ChangeSet changeSet = context.GetChangeSet();
            if (changeSet != null)
            {
                context.Refresh(refreshMode, changeSet.Deletes);
                context.Refresh(refreshMode, changeSet.Updates);
            }
        }
    }
    

    Refer to Linq to SQL - Discard Pending Changes

    0 讨论(0)
  • 2020-11-27 19:19

    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.

    0 讨论(0)
  • 2020-11-27 19:23

    My application is outlook style with a icon to select an active form (ListBox). Before allowing the user to change their context they have to accept changes or discard them.

    var changes = db.GetChangeSet();
    if ((changes.Updates.Count > 0) || (changes.Inserts.Count > 0) || (changes.Deletes.Count > 0))
    {
        if (MessageBox.Show("Would you like to save changes?", "Save Changes", MessageBoxButton.YesNo)  == MessageBoxResult.Yes)
        {
            db.SubmitChanges();
        } else
        {
            //Rollback Changes
            foreach (object objToInsert in changes.Inserts)
            {
                db.GetTable(objToInsert.GetType()).DeleteOnSubmit(objToInsert);
            }
            foreach (object objToDelete in changes.Deletes)
            {
                db.GetTable(objToDelete.GetType()).InsertOnSubmit(objToDelete);
            }
            foreach (object objToUpdate in changes.Updates)
            {
                db.Refresh(RefreshMode.OverwriteCurrentValues, objToUpdate);
            }
            CurrentForm.SetObject(null); //Application Code to Clear active form
            RefreshList(); //Application Code to Refresh active list
        }
    }
    
    0 讨论(0)
  • 2020-11-27 19:24

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

    For example

    dataContext.Refresh(RefreshMode.OverwriteCurrentValues, someObject);
    
    0 讨论(0)
提交回复
热议问题