Bagaimana saya bisa menolak semua perubahan dalam Linq untuk SQL's DataContext?

Pada Linq untuk SQL's DataContext saya dapat panggilan SubmitChanges() untuk menyerahkan semua perubahan.

Apa yang saya inginkan adalah untuk entah bagaimana menolak semua perubahan dalam datacontext dan rollback semua perubahan baik (tanpa masuk ke database).

Apakah ini mungkin?

Mengapa tidak membuang data konteks dan hanya menggantinya dengan yang baru misalnya?

Komentar (3)

public static class DataContextExtensions
{
    /// 
    ///     Discard all pending changes of current DataContext.
    ///     All un-submitted changes, including insert/delete/modify will lost.
    /// 
    /// <param name="context">A value that specifies how optimistic concurrency conflicts are handled.
Komentar (2)
Larutan

Di .bersih 3.0 menggunakan db.GetChangeSet().Update.Jelas() untuk diperbarui, db.GetChangeSet().Sisipan.Jelas() untuk baru atau db.GetChangeSet().Menghapus.Jelas() untuk item yang dihapus.

Di .net 3.5 dan atas hasil GetChangeSet() sekarang readonly, lingkaran koleksi di untuk atau foreach dan refresh setiap ChangeSet tabel seperti juga macias menulis di komentar.

Komentar (4)

Panggilan Clear() di Update, Menghapus dan Menyisipkan koleksi tidak bekerja.

GetOriginalEntityState() dapat berguna, tetapi hanya memberikan Id untuk foreign key hubungan, bukan entitas yang sebenarnya sehingga anda're kiri dengan terpisah objek.

Berikut ini's sebuah artikel yang menjelaskan bagaimana untuk membuang perubahan dari data konteks: http://graemehill.ca/discard-changes-in-linq-to-sql-datacontext

EDIT: Memanggil Refresh() akan membatalkan update, tapi tidak menghapus dan menyisipkan.

Komentar (0)

Sebagai Haacked mengatakan, hanya drop konteks data.

Anda mungkin seharusnya't simpan data konteks hidup untuk waktu yang lama. Mereka're dirancang untuk digunakan di transaksional cara (yaitu satu konteks data per atom unit kerja). Jika anda menyimpan data konteks hidup untuk waktu yang lama, anda menjalankan risiko yang lebih besar menghasilkan concurrency terkecuali ketika anda memperbarui basi badan.

Komentar (0)

Refresh akan bekerja, namun anda harus memberikan badan yang ingin anda reset.

Misalnya

dataContext.Refresh(RefreshMode.OverwriteCurrentValues, someObject);
Komentar (1)

Anda dapat menggunakan GetOriginalEntityState(..) untuk mendapatkan nilai-nilai asli untuk benda-benda misalnya Pelanggan menggunakan cache yang lama nilai-nilai.

Anda juga dapat iterate melalui perubahan misalnya update dan refresh benda-benda tertentu saja dan tidak seluruh tabel karena kinerja hukuman akan tinggi.

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

ini akan mengembalikan perubahan yang bertahan menggunakan data dalam database.

Solusi lain adalah untuk membuang datacontext yang anda gunakan, menggunakan Dispose().

Dalam kasus apapun, itu adalah praktik yang baik untuk menimpa Menyisipkan dan Menghapus metode dalam pengumpulan misalnya Pelanggan yang anda gunakan dan tambahkan misalnya InsertOnSubmit() call. Ini akan menyelesaikan masalah anda dengan pending Insersi dan Penghapusan.

Komentar (0)

Sangat baik menulis di atas di sini, tapi di sini adalah copy dan paste kode yang digunakan.

Public Sub DiscardInsertsAndDeletes(ByVal data As DataContext)
    ' Get the changes
    Dim changes = data.GetChangeSet()

    ' Delete the insertions
    For Each insertion In changes.Inserts
        data.GetTable(insertion.GetType).DeleteOnSubmit(insertion)
    Next

    ' Insert the deletions
    For Each deletion In changes.Deletes
        data.GetTable(deletion.GetType).InsertOnSubmit(deletion)
    Next
End Sub

Public Sub DiscardUpdates(ByVal data As DataContext)
    ' Get the changes
    Dim changes = data.GetChangeSet()

    ' Refresh the tables with updates
    Dim updatedTables As New List(Of ITable)
    For Each update In changes.Updates
        Dim tbl = data.GetTable(update.GetType)
        ' Make sure not to refresh the same table twice
        If updatedTables.Contains(tbl) Then
            Continue For
        Else
            updatedTables.Add(tbl)
            data.Refresh(RefreshMode.OverwriteCurrentValues, tbl)
        End If
    Next
End Sub
Komentar (3)

Saya aplikasi outlook dengan gaya ikon untuk memilih bentuk aktif (ListBox). Sebelum memungkinkan pengguna untuk mengubah konteks mereka untuk menerima perubahan atau membuang mereka.

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
    }
}
Komentar (0)

Berikut adalah bagaimana saya melakukannya. Saya hanya mengikuti Teddy's contoh di atas dan modern itu. Saya punya satu pertanyaan meskipun, mengapa repot-repot dengan me-refresh pada MENGHAPUS?

  public static bool UndoPendingChanges(this NtsSuiteDataContext dbContext)
  {
     if (dbContext.ChangesPending())
     {
        ChangeSet dbChangeSet = dbContext.GetChangeSet();

        dbContext.Refresh(RefreshMode.OverwriteCurrentValues, dbChangeSet.Deletes);
        dbContext.Refresh(RefreshMode.OverwriteCurrentValues, dbChangeSet.Updates);

        //Undo Inserts
        foreach (object objToInsert in dbChangeSet.Inserts)
        {
           dbContext.GetTable(objToInsert.GetType()).DeleteOnSubmit(objToInsert);
        }

        //Undo deletes
        foreach (object objToDelete in dbChangeSet.Deletes)
        {
           dbContext.GetTable(objToDelete.GetType()).InsertOnSubmit(objToDelete);
        }
     }

     return true;
  }
Komentar (0)