DataTable’de DeÄŸiÅŸen Kayıtların Bilgisi [VB.NET, C#]

C#, VB.NET, ASP.NET Add comments

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.

  • Added: Sözkonusu satır, DataRowCollection koleksiyonuna eklendi ve henüz AcceptChanges() metodu çaÄŸrılmamış.
  • Delete: DataRow nesnesinin Delete() metodu kullanılarak veri tablosundan silinmiÅŸ.
  • Detached: Bu satıra ait DataRows nesnesi oluÅŸturulmuÅŸ fakat henüz DataRowCollection koleksiyonuna eklenmemiÅŸ yani veri tablosuna yansıtılmamış. Bu durum, satırın, oluÅŸturulma ve Add() metoduyla DataTable’e eklenme aÅŸamaları arasında olduÄŸunu gösterir.
  • Modified: Satırda güncelleme yapılmış ama güncelleme onaylanmamış yani henüz AcceptChanges() metodu çaÄŸrılmamış.
  • Unchanged: Bu satır, başından beri veya AcceptChanges() metodunun çaÄŸrılmasından bu yana deÄŸiÅŸmemiÅŸ.

    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.

  • Current: Satırın en sonki güncel deÄŸeri içerdiÄŸi versiyonu. EÄŸer satırın RowState property’si Deleted deÄŸerindeyse DataRowVersion için Current deÄŸeri oluÅŸmaz.
  • Original: Satırın orijinal deÄŸeri içerdiÄŸi versiyonu. EÄŸer satırın RowState property’si Added modundaysa DataRowVersion için Original deÄŸeri oluÅŸmaz.
  • Proposed: Yapılması düşünülen, niyetlenen deÄŸiÅŸikliÄŸi(proposed change) belirtir. Bunlar, DataRow nesnesinin BeginEdit() ve EndEdit() veya CancelEdit() metodları arasında yapılan deÄŸiÅŸikliklerdir. Yani BeginEdit() metodu çaÄŸrılmıştır fakat EndEdit() veya CancelEdit() metodları çaÄŸrılmamıştır. CancelEdit() metodun çaÄŸrılmasıyla satırın proposed sürümü silinir. Bu yüzden bir satırın proposed versiyonuna RowChanging, ColumnChanged gibi eventlere ait metodlarda eriÅŸilebilir.
  • Default: Bu deÄŸer, o satır için varsayılan satır versiyonunu(default row version) ne olacağını belirtir. EÄŸer satırın RowState property’si, Added, Modified veya UnChanged deÄŸerindeyse bu satırın default row versiyonu Current olandır. EÄŸer RowState property’si Deleted deÄŸerindeyse satırın default row versiyonu Original olur. EÄŸer RowState property’si Detached modundaysa satırın default row versiyonu Proposed olur.

    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.

  • Leave a Reply


    7 − 5 =

    WP Theme & Icons by N.Design Studio
    Entries RSS Comments RSS GiriÅŸ