2009-04-02 49 views
7

Làm cách nào để lấy DataTable và chuyển đổi nó thành Danh sách?DataTable vào Danh sách <object>

Tôi đã bao gồm một số mã bên dưới trong cả C# và VB.NET, vấn đề với cả hai điều này là chúng tôi tạo một đối tượng mới để trả về dữ liệu, rất tốn kém. Tôi cần trả lại một tham chiếu đến đối tượng.

Đối tượng DataSetNoteProcsTableAdapters.up_GetNoteRow thực hiện giao diện INote.

Tôi đang sử dụng ADO.NET, cùng với .NET 3.5

C# mã

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 Mã

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

Bất kỳ lý do tại sao bạn không sử dụng LINQ2SQL cho việc này? –

+0

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

+0

Khách hàng không muốn sử dụng LINQ2SQL hoặc LINQ nói chung. Cảm ơn bạn đã liên kết, nó sẽ giúp ích rất nhiều. Tôi sẽ chạy một số lần và xem điều gì xảy ra – Coppermill

Trả lời

2

Không, việc tạo danh sách không tốn kém. So với việc tạo bảng dữ liệu và tìm nạp dữ liệu từ cơ sở dữ liệu, nó rất rẻ.

Bạn có thể làm cho nó thậm chí còn rẻ hơn bằng cách tạo ra danh sách sau khi Populating bảng, do đó bạn có thể thiết lập công suất ban đầu với số hàng mà bạn sẽ đưa vào nó:

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

chắc chắn bạn có nghĩa là IList ghi chú = new List (table.Rows) nếu bạn làm điều bạn nhận được lỗi sau 'Public Sub New (bộ sưu tập AsIEnumerable (Tất INote)) ': chuyển đổi tiềm ẩn từ' DataRowCollection 'thành' IEnumerable (Of Inote) '. – Coppermill

+5

Không, anh ấy có nghĩa là những gì anh ấy viết. Điều đó sẽ làm cho danh sách được đặt thành kích thước của tập hợp kết quả. – Jake

-1

Nếu các thuộc tính của danh sách phù hợp với tên trường trong datatable bạn sẽ có thể tạo ra một số loại thói quen phản ánh chung chung.

+0

Nhưng không cần tạo đối tượng mới, nó phải tham chiếu đối tượng. – Coppermill

0

Bạn có muốn tham chiếu các hàng của bảng không? Trong trường hợp đó, bạn nên sử dụng thuộc tính DataTable.Rows.

Hãy thử điều này:

notes.AddRange(table.Rows); 

Nếu hàng bảng thực hiện INote thì đây nên làm việc.

Hoặc bạn có thể làm như bạn đã làm ở trên:

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

Đây là trên table.Rows Warning lỗi Runtime có thể xảy ra khi chuyển đổi 'System.Data.DataRowCollection' thành 'System.Collections.Generic.IList (Of.INote)' này được tạo ra một đối tượng mới, đó là những gì tôi đang cố gắng tránh – Coppermill

+0

Không, điều này không nên tạo ra các đối tượng mới. Tất cả những gì bạn đang làm là chuyển đối tượng sang một loại khác. –

1

Tại sao không vượt qua DataTable vào đến chức năng thay vì instantiating nó? Điều đó đơn giản chỉ chứa một tham chiếu.

Đó là cách quá đơn giản một câu trả lời quá đáng giá với bạn tôi chắc chắn, nhưng tôi không thấy nó không giải quyết được vấn đề của bạn như thế nào.

+0

tôi sau một INote để được trả lại – Coppermill

1

Không chắc chắn nếu điều này là những gì bạn đang tìm kiếm nhưng bạn có thể thử một cái gì đó như thế này.

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; 
    } 
} 

Đây là những gì tôi đã làm để hy vọng điều này sẽ hữu ích. Không chắc chắn nếu nó là đúng cách để làm điều đó nhưng nó hoạt động cho những gì chúng tôi cần nó cho.

+0

Điều này tạo ra một đối tượng mới, tôi cần mã để tham chiếu đối tượng Danh mục cat = new Category(); Hầu như Thể loại cat = (danh sách ) tables.Rows Nhưng điều đó không làm việc – Coppermill

+0

với điều đó bạn có thể lập bản đồ mà các thuộc tính bạn muốn sử dụng. đó là một cách tiếp cận lớn hơn nhưng không kém –

6

Tôi có một cách tiếp cận khác có thể đáng xem. Đó là một phương pháp trợ giúp. Tạo tệp lớp tùy chỉnh có tên CollectionHelper:

public static IList<T> ConvertTo<T>(DataTable table) 
    { 
     if (table == null) 
      return null; 

     List<DataRow> rows = new List<DataRow>(); 

     foreach (DataRow row in table.Rows) 
      rows.Add(row); 

     return ConvertTo<T>(rows); 
    } 

Hãy tưởng tượng bạn muốn có danh sách khách hàng.Bây giờ bạn sẽ có người gọi sau đây:

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

Các thuộc tính bạn có trong DataTable của bạn phải phù hợp với lớp khách hàng (lĩnh vực như tên, địa chỉ, điện thoại).

Tôi hy vọng điều đó sẽ hữu ích!

Đối với những người sẵn sàng để biết tại sao để sử dụng danh sách thay vì DataTables: link text

Các mẫu đầy đủ:

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

+1

stackoverflow chỉ cho phép tôi cung cấp cho bạn một điểm, 2 ++ –

+0

chuyển đổi này có thể được thực hiện với một nhà quản trị dữ liệu không? –

+0

Tôi đã lang thang nếu có thể tránh được điều này "phải khớp" cho thuộc tính lớp và trường dữ liệu! –

Các vấn đề liên quan