DataTable’da Distinct ve TOP N Örneği

ADO.NET’in önemli üyesi olan DataTable nesnesi üzerinde arama yaparken distinct (tekilleştirme) veya top n (üstten belli sayıda satır seçme) işlemlerine ihtiyaç duyabiliriz. Bu işlemleri çoğu zaman VTYS üzerinde yapmak mantıklı görünse de özellikle bağlantısız katman işlemlerinde veritabanına gitmeksizin bu işlemleri yapmak işlemleri hızlandırır. Bu yazıda bununla ilgili basit bir örnek vereceğiz.
Distinct işlemi için DataTable nesnesinin ToTable() yordamı kullanılır. ADO.NET 2.0 ile birlikte gelmiş olan bu yordam, DataView içerisindeki kayıtları yeni bir DataTable nesnesine aktarmanın en kısa yoludur. ToTable() yordamı, overload edilmiş olup verileri olduğu gibi tabloya aktarabildiği gibi verilecek parametreler doğrultusunda belirli kolon veya kolonlar üzerinde DISTINCT işlemini uygulayarak verileri tabloya aktarabilir. ToTable() yordamının prototipi şu şekildedir;

Public Function ToTable() As DataTable
Public Function ToTable(ByVal tableName As String) As DataTable
Public Function ToTable(ByVal distinct As Boolean, _
    ByVal ParamArray columnNames As String()) As DataTable
Public Function ToTable(ByVal tableName As String, _
    ByVal distinct As Boolean, _
    ByVal ParamArray columnNames As String()) As DataTable
public DataTable ToTable();
public DataTable ToTable(string tableName);
public DataTable ToTable(bool distinct,
    params string[] columnNames);
public DataTable ToTable(string tableName, bool distinct,
    params string[] columnNames);

Bu yordamı bir örnek üzerinde gösterelim.

Dim oDt As New DataTable("Table")
oDt.Columns.Add("No")
oDt.Columns.Add("AdSoyad")

oDt.Rows.Add("10", "Ahmet")
oDt.Rows.Add("10", "Ahmet")
oDt.Rows.Add("11", "Mehmet")

Dim oDv As DataView = oDt.DefaultView
oDv.RowFilter = "No>9"

'View'deki kayıtları No ve AdSoyad kolonlarına göre distinct yapıp Tablo ismindeki yeni bir tabloya aktarsın
Dim oTb As DataTable = oDv.ToTable("Tablo", True, _
    New String() {"No", "AdSoyad"})

For Each oDr As DataRow In oTb.Rows
    Console.WriteLine(oDr("No") + " " + oDr("AdSoyad"))
Next
DataTable oDt = new DataTable("Table");
oDt.Columns.Add("No");
oDt.Columns.Add("AdSoyad");

oDt.Rows.Add("10", "Ahmet");
oDt.Rows.Add("10", "Ahmet");
oDt.Rows.Add("11", "Mehmet");

DataView oDv = oDt.DefaultView;
oDv.RowFilter = "No>9";

//View'deki kayıtları No ve AdSoyad kolonlarına göre distinct yapıp Tablo ismindeki yeni bir tabloya aktarsın
DataTable oTb = oDv.ToTable("Tablo", true,
    new string[] {"No","AdSoyad"});

foreach(DataRow oDr in oTb.Rows)
    Console.WriteLine(oDr["No"] +" "+ oDr["AdSoyad"]);

10 Ahmet
11 Mehmet

Eğer burada distinct işlemini yaptırmamış olsaydık. “Ahmet” kaydı iki defa yazılacaktı.
Bir veri tablosunda en üstteki veya en alttaki n tane kaydı okumak isteyebiliriz. DataTable veya DataView nesneleri üzerinde doğrudan “TOP N” işlemini yaptıracak bir yordam bulunmamaktadır. Bunun yapmanın en kolay yolu, DataView veya DataTable kayıtlarını döngüye sokarak istenilen kayıt kadar okuma yapılıp okunan kayıtların yeni bir nesneye aktarılmasıdır. Eğer tabloda arada eksik kayıt içermeyen identity kolonu varsa bu kolon referans alınarak kolayca “TOP N” işlemi yapılabilir (DataTable.Select (“IdentiyKolon<> gibi). Fakat tablodaki tüm kayıtlar arasındaki değil belirli şartlara uyan kayıtlar arasından seçim yapılacak o zaman en mantıklısı döngü yöntemini kullanmaktır.

Sub Main()
    'Tek kolonlu bir tablo
    Dim oDt As New DataTable("Tablo")
    oDt.Columns.Add(New DataColumn("No", GetType(Int32)))
    oDt.Columns.Add(New DataColumn("Aciklama"))

    '10 kayıt ekleyelim
    Dim oDr As DataRow
    For i As Integer = 0 To 9
        oDr = oDt.NewRow()
        oDr("No") = (i + 1)
        oDr("Aciklama") = "Kayit " & (i + 1)
        oDt.Rows.Add(oDr)
    Next

    'DataView nesnesi oluşturalım
    Dim oDv As New DataView(oDt)
    'Numarası, 4'ten büyük olanları alalım
    oDv.RowFilter = "No>4"
    oDv.Sort = "Aciklama DESC"

    'Tabloda ilk 5 satırı seçelim.
    Dim oDvTop5 As DataView = GetTopRows(oDv, 5)
    Console.WriteLine("----Tablodaki İlk 5 Satır----")
    Console.WriteLine("[No]" & Chr(9) & "[Aciklama]")
    Console.WriteLine("----" & Chr(9) & "----------")

    For i As Integer = 0 To oDvTop5.Count - 1
        Console.WriteLine(oDv(i)("No") & "" & Chr(9) & _
            "" & oDv(i)("Aciklama"))
    Next
    Console.ReadLine()
End Sub

'oDv parametresi, üzerinde işlem yapacağı DataView'i belirtir
'N parametresi de oDv kaynağından kaç kayıt alması gerektiğini bildirir
Function GetTopRows(ByVal oDv As DataView, ByVal N As Integer) As DataView
    'Ara bir DataTable oluşturalım
    'Bu tablo, kaynak tablonun aynısı olmalıdır
    Dim oTbHedef As DataTable = oDv.Table.Clone()
    'Kaç kayıt isteniyorsa kaynak view'den o kadar okuyalım
    'Eğer istenilen kayıt sayısı, kaynak tablodaki satır sayısını aşıyorsa sistem hata vermesin
    If N >= oDv.Count Then
        N = oDv.Count
    End If
    For i As Integer = 0 To N - 1
        oTbHedef.ImportRow(oDv(i).Row)
    Next

    Return New DataView(oTbHedef)
End Function

static void Main(string[] args) {
//Tek kolonlu bir tablo
DataTable oDt = new DataTable(“Tablo”);
oDt.Columns.Add( new DataColumn(“No”,typeof(Int32)));
oDt.Columns.Add(new DataColumn(“Aciklama”));

//10 kayıt ekleyelim
DataRow oDr;
for (int i = 0; i
----Tablodaki İlk 5 Satır----
[No] [Aciklama]
---- ----------
9 Kayit 9
8 Kayit 8
7 Kayit 7
6 Kayit 6
5 Kayit 5

DataTable’da Distinct ve TOP N Örneği” üzerine bir düşünce

  1. Ahmet Kaymaz Yazar

    ToTable() yordamı DataTable sınıfına ADO.NET 2.0 ile birlikte eklendi. ADO.NET 1.0 veya ADO.NET 1.1 platformunda distinct işlemi için ara DataTable’ler kullanarak gerçekleştirebilirsiniz.

    Cevapla

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Time limit is exhausted. Please reload CAPTCHA.