【サンプル C#】
///
/// 更新中のDataSetに最新のDataSetをマージする
///
/// param name="dsBase":元となるDataSet
/// param name="dsNew":更新するDataSet
/// param name="IndexName":キーとなる列名の文字列配列(配列の順番はTabel順)
public static void DataSetUpdate( DataSet dsBase, DataSet dsNew, string[] IndexName )
{
//Debug.WriteLine("DataSetUpdate:開始");
// 元のDataSetから更新情報を抽出
DataSet dsUpd = dsBase.GetChanges();
// 削除用として元のDataSetの複製を生成
DataSet dsDel = dsBase.Clone();
// 削除分DataSetの追加扱い処理時のリレーション制約解除
dsDel.EnforceConstraints = false;
// 元のDataSetの非更新情報の内、最新DataSetに無いレコードを抽出&元DataSetから削除
for ( int nTbl=0 ; nTbl < dsBase.Tables.Count ; nTbl++ )
{
DataTable tbl = dsBase.Tables[nTbl];
int index = tbl.Columns.IndexOf(IndexName[nTbl]);
foreach ( DataRow drBase in tbl.Select( "", "", DataViewRowState.Unchanged ))
{
DataRow drNew = dsNew.Tables[nTbl].Rows.Find(drBase[index]);
if ( drNew == null )
{
// 削除分の保存と元データから削除
dsDel.Tables[nTbl].ImportRow(drBase);
tbl.Rows.Remove(drBase);
}
}
// 追加分を元データから削除
foreach ( DataRow drBase in tbl.Select( "", "", DataViewRowState.Added ))
{
tbl.Rows.Remove(drBase);
}
}
// 再読込みデータを旧データに反映
dsBase.Merge(dsNew);
// 更新ステータスをクリア
dsBase.AcceptChanges();
// 追加分を含む更新情報を旧データに反映
if ( dsUpd != null )
{
//Debug.WriteLine("DataSetUpdate dsUpd : " + dsUpd.Tables.Count.ToString());
for ( int nTbl=0 ; nTbl < dsBase.Tables.Count ; nTbl++ )
{
DataTable tbl = dsBase.Tables[nTbl];
int index = tbl.Columns.IndexOf(IndexName[nTbl]);
//Debug.WriteLine("DataSetUpdate dsUpd.Tables[" + tbl.TableName + "] : " + tbl.Rows.Count.ToString());
// 更新レコードを反映
foreach ( DataRow dr in dsUpd.Tables[nTbl].Select( "", "", DataViewRowState.ModifiedCurrent ))
{
DataRow drBase = tbl.Rows.Find(dr[index]);
if ( drBase == null )
{
tbl.ImportRow(dr);
}
else
{
// 既存レコードに値を代入
foreach ( DataColumn col in tbl.Columns )
{
//自動インクリメント列は除く
if ( col.AutoIncrement )
continue;
// 既存レコードに値を代入
drBase[col.Ordinal] = dr[col.Ordinal];
}
}
}
// 新規追加レコードを反映
foreach ( DataRow dr in dsUpd.Tables[nTbl].Select("", "", DataViewRowState.Added))
{
DataRow drBase = tbl.Rows.Find(dr[index]);
if ( drBase == null )
{
tbl.ImportRow(dr);
}
else
{
// 既存レコードに値を代入
foreach ( DataColumn col in tbl.Columns )
{
//自動インクリメント列は除く
if ( col.AutoIncrement )
continue;
// 既存レコードに値を代入
drBase[col.Ordinal] = dr[col.Ordinal];
}
}
}
}
// 抽出データの開放
dsUpd.Dispose();
}
// 最新版DataSetに存在しないレコードを追加扱いとする
if ( dsDel != null )
{
for ( int nTbl=0 ; nTbl < dsBase.Tables.Count ; nTbl++ )
{
DataTable tbl = dsBase.Tables[nTbl];
int index = tbl.Columns.IndexOf(IndexName[nTbl]);
// 最新版DataSetに存在しないレコードを追加
foreach ( DataRow dr in dsDel.Tables[nTbl].Rows )
{
DataRow drBase = tbl.Rows.Find(dr[index]);
if ( drBase == null )
{
drBase = tbl.NewRow();
// 新規レコードに値を代入(自動インクリメント列は除く)
foreach ( DataColumn col in tbl.Columns )
{
//自動インクリメント列は除く
if ( col.AutoIncrement )
continue;
// 新規レコードに値を代入
drBase[col.Ordinal] = dr[col.Ordinal];
}
tbl.Rows.Add(drBase);
}
}
}
// 抽出データの開放
dsDel.Dispose();
}
//Debug.WriteLine("DataSetUpdate:終了");
}
|