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?
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);
}
}
}
Merujuk ke Linq untuk SQL - Membuang Perubahan Tertunda
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.
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.
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.
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.
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
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
}
}
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;
}