2009-10-19 52 views
35

Tôi tham gia vào quá trình học tập C# và nó đang diễn ra tốt đẹp cho đến nay. Tuy nhiên tôi vừa mới đánh đầu tiên của tôi "nói gì?" chốc lát.DataTable, Cách điều kiện xóa các hàng

DataTable cung cấp truy cập hàng ngẫu nhiên vào bộ sưu tập hàng của nó, không chỉ thông qua hành vi thu thập điển hình, mà còn thông qua DataTable.Select. Tuy nhiên tôi dường như không thể liên kết khả năng này với DataRow.Delete. Cho đến nay đây là những gì nó có vẻ như tôi cần phải làm để có điều kiện xóa một hoặc nhiều hàng từ một bảng.

int max = someDataTable.Rows.Count - 1; 
for(int i = max; i >= 0; --i) 
{ 
    if((int)someDataTable.Rows[i].ItemArray[0] == someValue) 
    { 
     someDataTable.Rows[i].BeginEdit(); 
     someDataTable.Rows[i].Delete(); 
    } 
    else 
     break; 
} 
someDataTable.AcceptChanges(); 

Nhưng tôi không hài lòng với mã này. Tôi không bị thuyết phục. Chắc chắn là tôi đang thiếu gì đó. Tôi có thực sự buộc phải nhấn vào bộ sưu tập Hàng tuần tự nếu tôi cần xóa một hoặc nhiều hàng có điều kiện không?

(không nhớ ngược cho. Tôi xóa từ ngày kết thúc của DataTable. Vì vậy, nó là ok)

Trả lời

66

Bạn có thể truy vấn dữ liệu và sau đó lặp các hàng được lựa chọn để thiết lập chúng như xóa.

var rows = dt.Select("col1 > 5"); 
foreach (var row in rows) 
    row.Delete(); 

... và bạn cũng có thể tạo ra một số phương pháp khuyến nông để làm cho nó dễ dàng hơn ...

myTable.Delete("col1 > 5"); 

public static DataTable Delete(this DataTable table, string filter) 
{ 
    table.Select(filter).Delete(); 
    return table; 
} 
public static void Delete(this IEnumerable<DataRow> rows) 
{ 
    foreach (var row in rows) 
     row.Delete(); 
} 
+0

Ah! Đã không xảy ra với tôi Chọn() sẽ trả về một tham chiếu đến các hàng có thể định. Tôi biết tôi đã phải mất một cái gì đó. Cảm ơn nhiều! –

+0

Giải pháp quá tốt, điều này cũng giải quyết được vấn đề của tôi về datatable.select thay đổi thứ tự. – Signcodeindie

+0

Giải pháp tuyệt vời Matthew – Ravia

8

Tôi không có một cửa sổ hộp tiện dụng để thử loại này nhưng tôi nghĩ bạn có thể sử dụng một DataView và làm một cái gì đó như vậy:

DataView view = new DataView(ds.Tables["MyTable"]); 
view.RowFilter = "MyValue = 42"; // MyValue here is a column name 

// Delete these rows. 
foreach (DataRowView row in view) 
{ 
    row.Delete(); 
} 

Tôi chưa thử nghiệm điều này, mặc dù. Bạn có thể thử.

+0

Tôi đã thử và nó đã hoạt động. Tôi thích phương pháp Select. Nhưng điều tốt cần ghi nhớ. Cảm ơn :) +1 –

35

Dưới đây là một lớp lót bằng LINQ và tránh bất kỳ đánh giá thời gian chạy của chuỗi chọn: Phương pháp

someDataTable.Rows.Cast<DataRow>().Where(
    r => r.ItemArray[0] == someValue).ToList().ForEach(r => r.Delete()); 
+1

Tôi thực sự thích giải pháp này- rất hay - Cảm ơn! – MDV2000

+2

Thỉnh thoảng, hãy nhớ chức năng gọi someDataTable.AcceptChanges(); sau khi xóa –

+1

@GreyWolf nếu bạn muốn ghi các thay đổi về cơ sở dữ liệu, sau đó KHÔNG gọi AcceptChanges! AcceptChanges sẽ đánh dấu tất cả các hàng mới/cập nhật là không thay đổi, do đó DataAdapter sẽ nghĩ rằng không có thay đổi và sẽ không viết bất cứ thứ gì vào cơ sở dữ liệu trên .Update(). –

0

mở rộng dựa trên LINQ

public static void DeleteRows(this DataTable dt, Func<DataRow, bool> predicate) 
{ 
    foreach (var row in dt.Rows.Cast<DataRow>().Where(predicate).ToList()) 
     row.Delete(); 
} 

Sau đó sử dụng:

DataTable dt = GetSomeData(); 
dt.DeleteRows(r => r.Field<double>("Amount") > 123.12 && r.Field<string>("ABC") == "XYZ"); 
Các vấn đề liên quan