調べたい最も簡単な方法は、宛先テーブルを切り捨ててから、XMLインポートをそのテーブルに保存することです(AIをオフにして、必要に応じてインポートされたIDを使用します)。唯一の問題はそれを行う権利にあるかもしれません。それ以外の場合...
あなたがやろうとしていることはほぼ Merge
を使用して処理します 方法。ただし、削除された行を認識できない/認識しません。 メソッドはDataTables
に作用しているため 、行がマスターデータベースで削除された場合、その行はXML抽出に存在しません(RowState
とは異なります)。 Deleted
の )。これらはループで取り除くことができます。
同様に、新しい行はAIintに対して異なるPKを取得する可能性があります。これを防ぐには、宛先データベースで単純な非AI PKを使用して、任意の数を受け入れることができるようにします。
XMLの読み込み:
private DataTable LoadXMLToDT(string filename)
{
DataTable dt = new DataTable();
dt.ReadXml(filename);
return dt;
}
マージコード:
DataTable dtMaster = LoadXMLToDT(@"C:\Temp\dtsample.xml");
// just a debug monitor
var changes = dtMaster.GetChanges();
string SQL = "SELECT * FROM Destination";
using (MySqlConnection dbCon = new MySqlConnection(MySQLOtherDB))
{
dtSample = new DataTable();
daSample = new MySqlDataAdapter(SQL, dbCon);
MySqlCommandBuilder cb = new MySqlCommandBuilder(daSample);
daSample.UpdateCommand = cb.GetUpdateCommand();
daSample.DeleteCommand = cb.GetDeleteCommand();
daSample.InsertCommand = cb.GetInsertCommand();
daSample.FillSchema(dtSample, SchemaType.Source);
dbCon.Open();
// the destination table
daSample.Fill(dtSample);
// handle deleted rows
var drExisting = dtMaster.AsEnumerable()
.Select(x => x.Field<int>("Id"));
var drMasterDeleted = dtSample.AsEnumerable()
.Where( q => !drExisting.Contains(q.Field<int>("Id")));
// delete based on missing ID
foreach (DataRow dr in drMasterDeleted)
dr.Delete();
// merge the XML into the tbl read
dtSample.Merge(dtMaster,false, MissingSchemaAction.Add);
int rowsChanged = daSample.Update(dtSample);
}
何らかの理由で、rowsChanged
常に合計行数と同じ数の変更を報告します。ただし、Master / XML DataTableからの変更は、other/destinationテーブルに流れます。
削除コードは、既存のIDのリストを取得し、新しいXMLテーブルにそのIDの行があるかどうかによって、宛先DataTableから削除する必要のある行を決定します。欠落している行はすべて削除されてから、テーブルがマージされます。
キーはdtSample.Merge(dtMaster,false, MissingSchemaAction.Add);
です。 dtMaster
からのデータをマージします dtSample
を使用 。 false
paramは、着信XMLの変更が他のテーブルの値を上書きできるようにするものです(最終的にはデータベースに保存されます)。
AI PKが一致しないなどの問題のいくつかが大きな問題であるかどうかはわかりませんが、これで私が見つけたすべての問題を処理できるようです。実際には、あなたがやろうとしているのはデータベースの同期 。テーブルが1つで、行が数行しかない場合でも、上記は機能するはずです。