割と有名な話な気がしないでもないですが、開発中に一度躓いたので。。。




DataTableからDataRowを削除する方法は以下の二つです。


DataRowCollectionのRemoveメソッド(RemoveAtメソッドも同じ)を使用する。

 (DataTable.Rowsプロパティを使う)

DataRowのDeleteメソッドを使用する。


(参照:DataRowの削除  (外部リンク))



どう違うのかと言うと、

Remove メソッドは DataRowCollection から DataRow を削除しますが、一方の Delete メソッドは削除対象の行をマークするだけです。」


とのこと。


まぁ、どういうことなのかというと、だいたい以下のような違いが生まれます。


1.Removeメソッドにより行を削除した場合、DataSetのHasChangesメソッドの結果はfalseになる

2.Deleteメソッドにより行を削除した場合、DataRowCollection.CountとDataView.Countの結果に差異が出る


1.に関しては、HasChangesメソッド内で全行のDataRowStateを見ているらしく、

Removeメソッドによって行のオブジェクトが消えているため、削除行が検索対象にならずに起こるようです。


2.に関しては、まぁ、Deleteの場合にオブジェクトが消えてないから起こります。

サンプルの動作を見たほうが早いです。




↓以下、サンプル


・概要

 データセットを適当に作成し、DataTableに200行のデータを作成し、RemoveとDeleteで行を消す。


・環境

 Visual C# 2010 Express Edition


・ソース

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

namespace RowDeleteTest {
class Program {
static void Main(string[] args) {

DataSet ds = new DataSet("MyDataSet");

ShowMessage("DataSetを生成しました。");

DataTable table = CreateTable(ds);

ShowMessage("テーブルを作成しました。");

AddRows(table, 200);

ShowMessage("行を作成しました。");

ds.AcceptChanges();

int nowCount = table.AsDataView().Count;

//最終行から2行、RemoveAtメソッドを用いて削除する
for (int i = nowCount - 1; i > nowCount - 3; i--) {

table.Rows.RemoveAt(i);
}

ShowMessage("RemoveAtメソッドにより、2行削除されました。");

if (ds.HasChanges()) {
ShowMessage("DataRowCollection.RemoveAtメソッドの結果、データセットに変更が加えられました。");
}

CountTableRows(table);
CountDataViewRows(table);

nowCount = table.AsDataView().Count;

for (int i = nowCount - 1; i > nowCount - 3; i--) {
DataRow row = table.Rows[i];
row.Delete();
}


      ShowMessage("Deleteメソッドにより、2行削除されました。");
if (ds.HasChanges()) {
ShowMessage("DataRow.Deleteメソッドの結果、データセットに変更が加えられました。");
}

CountTableRows(table);
CountDataViewRows(table);


ShowMessage("終了するにはキーを押してください。");

Console.ReadLine();
}

static void ShowMessage(string message) {

Console.WriteLine(message);
Console.WriteLine();
}

/// <summary>
/// データセットにテーブル追加
/// </summary>
/// <returns></returns>
static DataTable CreateTable(DataSet ds) {

DataTable result = null;
string formatStr = "MyDataTable{0}";
for (int i = 0; ; i++) {
string tableName = string.Format(formatStr, i);
if (!ds.Tables.Contains(tableName)) {
result = ds.Tables.Add(tableName);
break;
}
}

return result;
}

static void AddRows(DataTable table, int rowCount) {
table.Columns.Add();
for (int i = 0; i < rowCount; i++) {
table.Rows.Add(new object[] { i });
}
}

static void CountTableRows(DataTable table) {
int count = table.Rows.Count;
ShowMessage(string.Format("DataTable.Rows.Countの値は {0} です。", count));
}

static void CountDataViewRows(DataTable table) {
int count = table.AsDataView().Count;
ShowMessage(string.Format("DataTableのDataView.Countの値は {0} です。", count));

}
}
}

・結果

DataSetを生成しました。

テーブルを作成しました。

行を作成しました。

RemoveAtメソッドにより、2行削除されました。

DataTable.Rows.Countの値は 198 です。

DataTableのDataView.Countの値は 198 です。

Deleteメソッドにより、2行削除されました。

DataRow.Deleteメソッドの結果、データセットに変更が加えられました。

DataTable.Rows.Countの値は 198 です。

DataTableのDataView.Countの値は 196 です。

終了するにはキーを押してください。



だいたいこんな感じです。


躓いた備忘みたいなものでした。