2009-10-19 27 views
35

私はC#の学習プロセスに従事していますが、これまでのところうまくいきます。しかし、私はちょうど今、私の最初の "何を言う?"瞬間DataTable、行を条件付きで削除する方法

DataTableは、標準的なコレクションの動作だけでなく、DataTable.Selectを介して、Rowsコレクションへのランダムな行アクセスを提供します。しかし、私はこの能力をDataRow.Deleteに結びつけることができないようです。ここまでは、テーブルから1つ以上の行を条件付きで削除するために必要なことです。

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(); 

しかし、私はこのコードに満足していません。どちらも私は確信していません。私は何かを欠いているに違いない。条件付きで1つ以上の行を削除する必要がある場合は、実際に行コレクションを順番に実行する必要がありますか?

(私はデータテーブルの端から削除しています。のために反転し気にしない。それはOKですので)

答えて

66

あなたがデータセットと、ループの削除として、それらを設定するために選択した行を問い合わせることができます。

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

...そしてあなたもそれを容易にするために、いくつかの拡張メソッドを作成することができます...

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

をああ!私には起こらなかったSelect()はデータテーブルの行への参照を返します。私は何かが欠けていなければならないことを知っていた。本当にありがとう! –

+0

これは良い解決策でもあります。これは、datatable.selectが注文を変更するという私の問題を解決しました。 – Signcodeindie

+0

素晴らしい解決策Matthew – Ravia

8

私は窓が、これを試して便利なボックスはありませんが、私はあなたが使用することができると思いますDataViewを実行して、次のようなことをしてください:

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

私はこれをテストしませんでした。試してみてください。

+0

私は試してみました。私はSelectアプローチを好む。しかし、心に留めておくのは良いことです。ありがとう:) +1 –

35

ここでLINQを使用し、選択した文字列のいずれかの実行時の評価を避けワンライナーです: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(); 
} 

に基づいて

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

私は本当にこのソリューションがとても気に入りました - ありがとう! – MDV2000

+2

いつか、関数someDataTable.AcceptChanges()を覚えておいてください。 –

+1

@GreyWolf変更をデータベースに書き戻したい場合は、AcceptChangesを呼び出さないでください! AcceptChangesはすべての新規/更新された行を変更されていない行としてマークします。したがって、DataAdapterは変更がないと判断し、.Update()でデータベースに何も書き込まれません。 –

0

拡張メソッドは、次に使用:

DataTable dt = GetSomeData(); 
dt.DeleteRows(r => r.Field<double>("Amount") > 123.12 && r.Field<string>("ABC") == "XYZ"); 
関連する問題