2009-04-02 27 views
7

DataTable'ı nasıl alabilirim ve bir listeye nasıl dönüştürürüm?DataTable Liste <object>

Hem C# hem de VB.NET'te aşağıdaki kodları ekledim, her ikisi de sorunu, verileri döndürmek için yeni bir nesne oluşturmamızdır, ki bu çok maliyetlidir. Nesneye bir başvuru göndermem gerekiyor.

DataSetNoteProcsTableAdapters.up_GetNoteRow nesnesi INote arabirimini uygular. .NET 3.5

C# kodu ile

public static IList<INote> GetNotes() 
{ 
    DataSetNoteProcsTableAdapters.up_GetNoteTableAdapter adapter = 
     new DataSetNoteProcsTableAdapters.up_GetNoteTableAdapter(); 
    DataSetNoteProcs.up_GetNoteDataTable table = 
     new DataSetNoteProcs.up_GetNoteDataTable(); 

    IList<INote> notes = new List<INote>(); 

    adapter.Connection = DataAccess.ConnectionSettings.Connection; 
    adapter.Fill(table); 

    foreach (DataSetNoteProcs.up_GetNoteRow t in table) { 
     notes.Add((INote)t); 
    } 

    return notes; 
} 

VB.NET Kod listesinin özellikleri alan adlarını

Public Shared Function GetNotes() As IList(Of INote) 
    Dim adapter As New DataSetNoteProcsTableAdapters.up_GetNoteTableAdapter 
    Dim table As New DataSetNoteProcs.up_GetNoteDataTable 

    Dim notes As IList(Of INote) = New List(Of INote) 

    adapter.Connection = DataAccess.ConnectionSettings.Connection 
    adapter.Fill(table) 

    For Each t As DataSetNoteProcs.up_GetNoteRow In table 
     notes.Add(CType(t, INote)) 
    Next 

    Return notes 
End Function 
+0

bir sebebi var? –

+0

Dup: http://stackoverflow.com/questions/545328/datatable-to-generic-list-memory-leak/545429#545429 –

+0

Müşteri genellikle LINQ2SQL veya LINQ kullanmak istemez. Bağlantı için teşekkürler, çok yardımcı olacaktır. Bazı zamanlar koşacağım ve ne olduğunu göreceğim – Coppermill

cevap

2

Hayır, bir liste oluşturmak maliyetli değildir. Veri tablosunu oluşturup veriyi veritabanından almakla kıyaslandığında çok ucuz.

Sen seni içine koymak olacaktır satır sayısına karşılık başlangıç ​​kapasitesine ayarlayabilirsiniz, böylece tablo yerleştirmenin ardından listesi oluşturarak bile ucuza yapabilirsiniz:

IList<INote> notes = new List<INote>(table.Rows.Count); 
+0

döndürülecek sonra aşağıdaki hatayı olsun yaparsanız ılist notları = new List (table.Rows) demek duyuyorum 'Ortak alt yeni (toplama AsIEnumerable (iNote Of)) ':' DataRowCollection 'ile' IEnumerable (Inote) 'arasındaki örtük dönüşümler. – Coppermill

+5

Hayır, yazdığı şeyden bahsediyor. Bu, listenin sonuç kümesinin boyutuna ayarlanmasına neden olur. – Jake

-1

eşleşirse boyunca

Ben ADO.NET kullanıyorum Veritabanında bir çeşit genel yansıma rutinini oluşturabilmelisiniz.

+0

Ancak yeni bir nesne oluşturmaya gerek yok, nesneye başvurmalı. – Coppermill

0

Tablonun satırlarına başvurmak ister misiniz? Bu durumda DataTable.Rows özelliğini kullanmalısınız.

bu deneyin: tablo satırları iNote uygularsanız o zaman bu çalışması gerekir

notes.AddRange(table.Rows); 

. Yukarıda olduğu gibi

Alternatif yapabilirdi:

foreach (INote note in table.Rows) 
{ 
    notes.Add(note) 
} 
+0

Bu, yeni bir nesne oluşturuyor 'System.Collections.Generic.IList (Of.INote)' için 'System.Data.DataRowCollection' dönüştürürken oluşabilir Çalışma hataları Uyarı table.Rows verildi, – Coppermill

+0

No'dan kaçınmaya çalıştığım şey budur, bu yeni nesneler oluşturmamalıdır. Yaptığınız tek şey nesneyi başka bir türe dökmek. –

1

Neden işlevine içine DataTable geçmesi yerine onu başlatmasını değil? Bu sadece bir referans içerir.

Bu kadar basit bir cevap da size çok faydalı olacaktır Eminim, ama sorununuzu nasıl çözmediğini göremiyorum.

+0

Bir iNote mutlaka – Coppermill

1

bu olursa emin Aradığın şey ama bunu böyle deneyebilirsin.

public class Category 
{ 
    private int _Id; 
    public int Id 
    { 
     get { return _Id; } 
     set { _Id = value; } 
    } 

    private string _Name = null; 
    public string Name 
    { 
     get { return _Name; } 
     set { _Name = value; } 
    } 

    public Category() 
    {} 

    public static List<Category> GetCategories() 
    { 
     List<Category> currentCategories = new List<Category>(); 

     DbCommand comm = GenericDataAccess.CreateTextCommand(); 
     comm.CommandText = "SELECT Id, Name FROM Categories Order By Name"; 
     DataTable table = GenericDataAccess.ExecuteSelectCommand(comm); 

     foreach (DataRow row in table.Rows) 
     { 
      Category cat = new Category(); 
      cat.Id = int.Parse(row["Id"].ToString()); 
      cat.Name = row["Name"].ToString(); 
      currentCategories.Add(cat); 
     } 
     return currentCategories; 
    } 
} 

Yaptığım şey budur, umarım bu yardımcı olur. Bunu yapmanın doğru yolu olup olmadığından emin değiliz ama bunun için ihtiyacımız olan şey için çalışıyor.

+0

Bu yeni bir nesne oluşturur, nesneyi başvurulan kodlara ihtiyacım var Kategori cat = new Kategori(); Neredeyse Kategori kedi = (liste ) tables.Rows Kullanmak istediğiniz nitelikleri eşleyebileceği ile Ama bu çalışmıyor – Coppermill

+0

gibi. Bu daha büyük bir yaklaşımdır fakat kötü değil –

6

Bakmaya değer başka bir yaklaşımım var. Bu bir yardımcı yöntemdir. CollectionHelper adında bir özel sınıf dosyası oluşturun: Müşterilerin bir listesini almak istediğinizi hayal edin.

List<Customer> myList = (List<Customer>)CollectionHelper.ConvertTo<Customer>(table); 

niteliklerini size DataTable var (İsim, Adres, Telefon gibi alanlar) Müşteri sınıfını aynı olmalıdır: Artık şu arayan gerekecek.

Umarım yardımcı olur! İçin

bilmek niçin DataTable yerine listeleri kullanmak isteyen: link text

tam örnek: Bunun için Linq2SQL kullanmıyorsanız neden

http://lozanotek.com/blog/archive/2007/05/09/Converting_Custom_Collections_To_and_From_DataTable.aspx

+1

stackoverflow sadece size bir puan vermeme izin veriyor, 2 ++ –

+0

bu dönüşüm bir datareader ile yapılabilir mi? –

+0

Sınıf öznitelikleri ve veri alanları için bu "eşleşmeli" olmasından kaçınmak mümkün olsaydı dolaşıyordum! –