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
.net 2003’te ToTable var mı?
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.
Çok teşekkürler, faydalı oldu ve zaman kazandırdı.Selamlar.