2009-08-12 14 views
6

Đầu tiên tôi phải nói, rằng tôi là người mới sử dụng LINQ. Trên thực tế tôi chưa bao giờ được sử dụng trước đây, nhưng tôi đang có một nhiệm vụ mà tôi cần phải lọc một DataTable, sử dụng các giá trị sẽ đến từ một danh sách. Vì vậy, tôi sẽ muốn biết nếu nó có thể trong LINQ để truy vấn trên một giá trị sử dụng có thể định vị trong danh sách dưới dạng giá trị Bộ lọc. Một số người có thể cho tôi một số gợi ý củaChọn hàng từ một tập dữ liệu bằng LINQ, trong đó danh sách các RowsID nằm trong danh sách <T>

Cảm ơn bạn.

Trả lời

7

Cách tốt nhất để làm điều này phụ thuộc vào những gì bạn dự định làm với kết quả được lọc. Bạn có cần kết quả trở lại như DataTable cho các hoạt động tiếp theo, hoặc là bạn databinding đến kết quả?

Lấy ví dụ dưới đây, mà trả về một (bindable) Enumerator của phù hợp với DataRows

//create sample table with sample rows 
DataTable table = new DataTable(); 

table.Columns.Add("id", typeof(int)); 

for (int i = 1; i < 11; i++) 
{ 
    DataRow row = table.NewRow(); 
    row[0] = i; 
    table.Rows.Add(row); 
} 

//filter the table by id (in a list) 
List<int> rowIds = new List<int> { 1, 3, 6 }; 

IEnumerable<DataRow> matchingRows = from DataRow row in table.Rows 
        where rowIds.Contains((int)row[0]) 
        select row; 

Nếu bạn cần một DataTable bạn có thể nhập khẩu các hàng vào bảng khác:

DataTable filteredTable = table.Clone(); 

foreach (DataRow filteredRow in matchingRows) 
{ 
    filteredTable.ImportRow(filteredRow); 
} 
+0

Một cách để chuyển đổi thành một datatable là sử dụng .CopyToDataTable(), trong trường hợp này hãy đảm bảo kiểm tra xem matchingRows.Any() có trả về true trước khi thực hiện matchingRows.CopyToDataTable() hay không. Điều này đòi hỏi System.Data.DataTableExtensions – Enrico

2

tôi thường cung cấp cho bản thân các phương thức mở rộng khi tôi cần xử lý đối tượng trước LINQ như một đối tượng LINQ đã sẵn sàng. Ví dụ, bạn đang tìm kiếm để truy vấn trên một DataRowCollection (DataTable.Rows bất động sản) mà bạn có thể không sử dụng cho bất cứ điều gì nhiều hơn một danh sách các DataRows. Tôi sẽ làm cho một phương pháp mở rộng mà không chuyển đổi này cho bạn (DataRowCollection để List<DataRow>). Tôi cũng thường sử dụng một phương pháp mở rộng để có được các giá trị một cách an toàn khi tôi không quan tâm để ném một ngoại lệ nếu vì một lý do nào đó một tên khóa không hợp lệ được cung cấp cho cột. Sau đó, bạn có thể tạo một phương thức mở rộng có danh sách các int như id và một tên trường chứa id để trả về những gì bạn muốn. Khi tất cả được nói và thực hiện, điều này được thực hiện với một dòng mã. Đây là lớp học với tất cả các phương pháp mở rộng của bạn.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Data; 

namespace ConsoleApplication11 
{ 
    public static class SystemDataHelpers 
    { 
     public static List<DataRow> RowList(this DataTable table) 
     { 
      List<DataRow> list = new List<DataRow>(); 
      foreach (DataRow row in table.Rows) 
       list.Add(row); 
      return list; 
     } 

     public static object GetItem(this DataRow row, string field) 
     { 
      if (!row.Table.Columns.Contains(field)) 
       return null; 
      return row[field]; 
     } 

     public static List<DataRow> GetRows(this DataTable table, List<int> ids, string fieldName) 
     { 
      Func<DataRow, bool> filter = row => ids.Contains((int)row.GetItem(fieldName)); 
      return table.RowList().Where(filter).ToList(); 
     } 
    } 
} 

Sau đó, ngoài việc thiết lập các biến (bạn không cần phải làm ... bạn đã có chúng), công việc thực hiện được thực hiện với một dòng mã (EDIT: một cuộc gọi phương thức duy nhất):

 DataTable table = new DataTable(); 
     List<int> rowIds = new List<int> { 1, 2, 3, 4 }; 
     string idFieldName = "row_id"; 

     List<DataRow> selected = table.GetRows(rowIds, idFieldName); 
Các vấn đề liên quan