DataTable, DataSet, DataRow gibi nesnelerdeki satırların durumu hakkında bilgi almak herhangi bir güncelleme olmuşsa hangi aşamada olduğunu öğrenmek için System.Data.DataRowState ve System.Data.DataRowVersion kavramları kullanılır.
DataRowState, veri tablosundaki her satırın durumunu belirtir. Özellikle satır güncelleme işlemlerini yönetmek amacıyla kullanılır. Her satırın bir RowState değeri vardır. DataRowState, aşağıdaki değerleri alabilir.
Bu seçenekleri kullanarak herhangi bir kayıt satırının hangi aşamada olduğunu, yani güncelleniyor, güncellenmiş veya güncellenmesi iptal edilmiş olup olmadığını kontrol edebiliriz.
'Yeni bir DataRow oluştur. oDr = oDt.NewRow() 'Detached row Console.WriteLine("NewRow() : " & oDr.RowState) 'Satırı, tabloya ekleyelim. oDt.Rows.Add(oDr) 'Added row Console.WriteLine("Rows.Add() : " & oDr.RowState) 'Değişiklikleri onaylayalım oDt.AcceptChanges() 'Unchanged row. Console.WriteLine("AcceptChanges() : " & oDr.RowState) 'Satırın AdSoyad kolonunu güncelleyelim. oDr("AdSoyad") = "Ahmet Kaymaz" 'Modified row. Console.WriteLine("Modified : " & oDr.RowState) 'Bu satırı silelim oDr.Delete() 'Deleted row. Console.WriteLine("Deleted : " & oDr.RowState)
//Yeni bir DataRow oluştur. oDr = oDt.NewRow(); //Detached row Console.WriteLine("NewRow() : " + oDr.RowState); //Satırı, tabloya ekleyelim. oDt.Rows.Add(oDr); //Added row Console.WriteLine("Rows.Add() : " + oDr.RowState); //Değişiklikleri onaylayalım oDt.AcceptChanges(); //Unchanged row. Console.WriteLine("AcceptChanges() : " + oDr.RowState); //Satırın AdSoyad kolonunu güncelleyelim. oDr["AdSoyad"] = "Ahmet Kaymaz"; //Modified row. Console.WriteLine("Modified : " + oDr.RowState); //Bu satırı silelim oDr.Delete(); //Deleted row. Console.WriteLine("Deleted : " + oDr.RowState);
NewRow() : Detached
Rows.Add() : Added
AcceptChanges() : Unchanged
Modified : Modified
Deleted : Deleted
Bilindiği gibi dataset içindeki veri tablosundan kayıt silmek için Remove() veya Delete() metodu kullanılır. Remove() metodu, sözkonusu satırı olduğu gibi satır koleksiyonundan uçurur ve satırın RowState’inden bir değişiklik yapmaz, Delete() ise satır sadece silinecek olarak işaretler ve RowState’ini “Deleted” olarak set eder.
oDt.AcceptChanges() Dim oDs As New DataSet() oDs.Tables.Add(oDt) 'İlk satırı Delete() ile silelim oDt.Rows(0).Delete() 'Deleted Console.WriteLine(oDt.Rows(0).RowState.ToString()) 'Deleted Console.WriteLine(oDs.HasChanges()) 'True 'İkinci satırı Remove() ile silelim oDt.Rows.Remove(oDt.Rows(1)) Console.WriteLine(oDt.Rows(1).RowState.ToString()) 'Unchanged Console.WriteLine(oDs.HasChanges()) 'False
oDt.AcceptChanges(); DataSet oDs= new DataSet(); oDs.Tables.Add(oDt); //İlk satırı Delete() ile silelim oDt.Rows[0].Delete();//Deleted Console.WriteLine(oDt.Rows[0].RowState);//Deleted Console.WriteLine(oDs.HasChanges());//True //İkinci satırı Remove() ile silelim oDt.Rows.Remove(oDt.Rows[1]); Console.WriteLine(oDt.Rows[1].RowState);//Unchanged Console.WriteLine(oDs.HasChanges());//False
ADO.NET 2.0 ile birlikte tablodaki satırlar üzerinde hakimiyetimiz artırılmış oldu. DataRow türündeki bir satırın RowState durumu manual olarak değiştirilebilir. Bunun için SetAdded() ve SetModified() metodları kullanılır. Bu metodların uygulanacağı satırların RowState durumlarının Unchanged olarak set edilmiş olması lazım. Yani bu metodlardan önce AcceptChanges() metodu çağrılarak tablodaki değişikliklerin onaylanması gerekir.
DataTable üzerinde çalışma zamanında ekleme, güncelleme, silme yapabildiğimiz için bu nesneyi asıl veritabanına göndermeye çalıştığımızda veri tutarlılığının olması gerekmektedir(Concurrency Exception – eş zamanlı uyumsuzluk durumu). Yani fiziksel veritabanındaki veriler, en son bizim çektiğimiz veriler olmalı, yani başka bir kullanıcı tarafından güncelleme yapılmamış olmalı. Çünkü daha sonra açıklayacağımız üzere DataAdapter, güncellemeleri database sunucusuna yansıtmaya çalışırken güncellenmiş verilerin orijinal değerlerini koşul olarak kullanır. Dolayısıyla bu süreçte her verinin default, asıl veya değişmiş versiyonu bulunur. Bu değişiklikler hakkında bilgiyi, DataRowVersion numaralandırıcısı verir. Herhangi bir satırda güncelleme yapıldığı zaman o satırın orijinal ve güncel olmak iki versiyonu oluşur. Bir satırın sözkonusu veriyonlarının olup olmadığı boolean türünde değer döndüren HasVersion() metoduyla kontrol edilir.
Herhangi bir satırın bu değerlerdeki satır versiyonuna erişmek için DataRow nesnesinin indexer’i kullanılır.
Default Public ReadOnly Property Item( _ ByVal column As DataColumn, _ ByVal version As DataRowVersion _ ) As Object Default Public ReadOnly Property Item( _ ByVal columnIndex As Integer, _ ByVal version As DataRowVersion _ ) As Object Default Public ReadOnly Property Item( _ ByVal columnName As String, _ ByVal version As DataRowVersion _ ) As Object
public object this[DataColumn column, DataRowVersion version]{get;} public object this[int columnIndex, DataRowVersion version] {get;} public object this[string columnName, DataRowVersion version] {get;}
'ColumnChanged event'i için bir handler tanımlayalım. AddHandler oDt.ColumnChanged, _ New DataColumnChangeEventHandler(AddressOf KolonDegisti) 'İlk değeri Ayşe olan bu kaydı Zeynep olarak güncelleyelim. oDt.Rows(1)("AdSoyad") = "Zeynep Korkmaz" Sub KolonDegisti(ByVal sender As Object, _ ByVal e As DataColumnChangeEventArgs) Console.WriteLine(e.Row("AdSoyad")) Console.WriteLine(e.Row("AdSoyad", DataRowVersion.Current)) Console.WriteLine(e.Row("AdSoyad", DataRowVersion.Original)) Console.WriteLine(e.Row("AdSoyad", DataRowVersion.[Default])) Console.WriteLine(e.Row("AdSoyad", DataRowVersion.Proposed)) End Sub
//ColumnChanged event'i için bir handler tanımlayalım. oDt.ColumnChanged += new DataColumnChangeEventHandler(KayitDegisti); //İlk değeri Ayşe olan bu kaydı Zeynep olarak güncelleyelim. oDt.Rows[1]["AdSoyad"] = "Zeynep Korkmaz"; static void KayitDegisti(object sender, DataColumnChangeEventArgs e) { Console.WriteLine(e.Row["AdSoyad"]); Console.WriteLine(e.Row["AdSoyad", DataRowVersion.Current]); Console.WriteLine(e.Row["AdSoyad", DataRowVersion.Original]); Console.WriteLine(e.Row["AdSoyad", DataRowVersion.Default]); Console.WriteLine(e.Row["AdSoyad", DataRowVersion.Proposed]); }
Zeynep Korkmaz
Ayşe Korkmaz - Current
Ayşe Korkmaz - Original
Zeynep Korkmaz - Default
Zeynep Korkmaz - Proposed
Tablodaki Değişiklikleri İzlemek
DataTable ile ilgili bahsececeğimiz diğer konu da tabloda yapılan değişikliklerin izlenmesidir. Veri tablosundaki eklenmiş, güncellenmiş veya silinmiş satırları yakalamak için DataTable nesnesinin GetChanges() metodu kullanılır. Bu metod, veri tablosundaki AcceptChanges() metodunun çağrılmasından sonraki tüm değişikliklerin bulunduğu bir DataTable nesnesi döndürür.
'Önceki tüm değişiklikleri onaylayalım oDt.AcceptChanges() 'İlk değeri Ayşe olan 2.satırı Zeynep olarak güncelleyelim. oDt.Rows(1)("AdSoyad") = "Zeynep Korkmaz" 'Yeni bir satır ekleyelim. oDr = oDt.NewRow() oDr("AdSoyad") = "Metin Güneş" oDr(2) = "10/10/1950" oDt.Rows.Add(oDr) 'Tablonun 2.satırını silelim oDt.Rows(1).Delete() 'İlk satırını Remove() ile silelim oDt.Rows.Remove(oDt.Rows(0)) 'Kaç satırın değiştiğini öğrenelim 'Değişiklik yapılmadığı zaman sistemin hata vermemesi için böyle bir kontrol gerekli If oDt.GetChanges() Is Nothing Then Console.WriteLine("Değişmiş satır bulunamadı.") Else Console.WriteLine("Değişmiş satır sayısı: {0}", oDt.GetChanges().Rows.Count) End If 'Değişmiş kayıtları oTb nesnesine alalım Dim oTb As DataTable = oDt.GetChanges() For Each oDr1 As DataRow In oTb.Rows 'Silinmiş kayıtların şu anki değerleri olmadığı için If oDr1.RowState = DataRowState.Deleted Then Console.Write("MusteriId: {0} ", _ oDr1("MusteriId", DataRowVersion.Original)) Console.Write("" Ad Soyad: {0}", _ oDr1("AdSoyad", DataRowVersion.Original)) Else Console.Write("MusteriId: {0} ", oDr1("MusteriId")) Console.Write("" Ad Soyad: {0}", oDr1("AdSoyad")) End If Console.Write(" " Durum: {0}", oDr1.RowState) Console.WriteLine() Next
//Önceki tüm değişiklikleri onaylayalım oDt.AcceptChanges(); //İlk değeri Ayşe olan 2.satırı Zeynep olarak güncelleyelim. oDt.Rows[1]["AdSoyad"] = "Zeynep Korkmaz"; //Yeni bir satır ekleyelim. oDr = oDt.NewRow(); oDr["AdSoyad"] = "Metin Güneş"; oDr[2] = "10/10/1950"; oDt.Rows.Add(oDr); //Tablonun 2.satırını silelim oDt.Rows[1].Delete(); //İlk satırını Remove() ile silelim oDt.Rows.Remove(oDt.Rows[0]) ; //Kaç satırın değiştiğini öğrenelim //Değişiklik yapılmadığı zaman sistemin hata vermemesi için böyle bir kontrol gerekli if (oDt.GetChanges() == null) Console.WriteLine("Değişmiş satır bulunamadı."); else Console.WriteLine("Değişmiş satır sayısı: {0}", oDt.GetChanges().Rows.Count); //Değişmiş kayıtları oTb nesnesine alalım DataTable oTb = oDt.GetChanges(); foreach (DataRow oR in oTb.Rows) { //Silinmiş kayıtların şu anki değerleri olmadığı için if (oR.RowState == DataRowState.Deleted) { Console.Write("MusteriId: {0} ", oR["MusteriId", DataRowVersion.Original]); Console.Write("" Ad Soyad: {0}", oR["AdSoyad", DataRowVersion.Original]); } else { Console.Write("MusteriId: {0} ", oR["MusteriId"]); Console.Write("" Ad Soyad: {0}", oR["AdSoyad"]); } Console.Write(" " Durum: {0}", oR.RowState); Console.WriteLine(); }
Değişmiş satır sayısı: 2
MusteriId: 1 " Ad Soyad: Ayşe Korkmaz " Durum: Deleted
MusteriId: 2 " Ad Soyad: Metin Güneş " Durum: Added
GetChanges() metodu, overload edilmiş olup DataRowState türünde parametre alan versiyonu da kullanılabilir. Bu durumda sadece belli durumlardaki satırları döndürür.
If oDt.GetChanges(DataRowState.Added) Is Nothing Then Console.WriteLine("Eklenmiş satır bulunamadı.") Else Console.WriteLine("Eklenmiş satır sayısı: {0}", oDt.GetChanges().Rows.Count) End If 'Sadece yeni eklenmiş kayıtları oTb nesnesine alalım Dim oTb As DataTable = oDt.GetChanges(DataRowState.Added) For Each oDr1 As DataRow In oTb.Rows Console.Write("MusteriId: {0} ", oDr1("MusteriId")) Console.Write("" Ad Soyad: {0}", oDr1("AdSoyad")) Console.Write(" " Durum: {0}", oDr1.RowState) Console.WriteLine() Next
if (oDt.GetChanges(DataRowState.Added) == null) Console.WriteLine("Eklenmiş satır bulunamadı."); else Console.WriteLine("Eklenmiş satır sayısı: {0}", oDt.GetChanges().Rows.Count); //Sadece yeni eklenmiş kayıtları oTb nesnesine alalım DataTable oTb = oDt.GetChanges(DataRowState.Added); foreach (DataRow oR in oTb.Rows) { Console.Write("MusteriId: {0} ", oR["MusteriId"]); Console.Write("" Ad Soyad: {0}", oR["AdSoyad"]); Console.Write(" " Durum: {0}", oR.RowState); Console.WriteLine(); }
Eklenmiş satır sayısı: 2
MusteriId: 2 " Ad Soyad: Metin Güneş " Durum: Added
Görüldüğü gibi GetChanges() metodu aracılığıyla dirty data denilen değişikliği henüz onaylanmamış kayıtları yakalama şansına sahibiz. Bu kayıtları, AcceptChanges() veya RejectChanges() metodlarını çağırdıktan sonra artık takip edemeyiz. Çünkü bu metodlar, veri tablosunda tutulan tüm değişiklik bilgileri siler.