Nejjednodušší způsob, kterým se možná budete chtít podívat, je ZKRÁTIT cílovou tabulku a poté do ní jednoduše uložit import XML (s vypnutou AI, aby v případě potřeby použila importované ID). Jediný problém může být s právy k tomu. Jinak...
To, o co se snažíte, může téměř lze zpracovat pomocí Merge
metoda. Nemůže/nebude však vědět o smazaných řádcích. Protože metoda funguje na DataTables
, pokud byl řádek smazán v hlavní databázi, nebude jednoduše existovat v XML extraktu (oproti RowState
z Deleted
). Ty lze odplevelit smyčkou.
Podobně mohou jakékoli nové řádky získat jinou PK pro AI int. Abyste tomu zabránili, stačí v cílové databázi použít jednoduchý PK bez AI, aby mohl přijímat libovolné číslo.
Načítání XML:
private DataTable LoadXMLToDT(string filename)
{
DataTable dt = new DataTable();
dt.ReadXml(filename);
return dt;
}
Slučovací kód:
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);
}
Z jakéhokoli důvodu rowsChanged
vždy hlásí tolik změn, kolik je celkem řádků. Změny z Master/XML DataTable však procházejí do jiné/cílové tabulky.
Odstraňovací kód získá seznam existujících ID a poté určí, které řádky je třeba odstranit z cílové tabulky DataTable podle toho, zda nová tabulka XML obsahuje řádek s tímto ID nebo ne. Všechny chybějící řádky jsou odstraněny a tabulky jsou sloučeny.
Klíč je dtSample.Merge(dtMaster,false, MissingSchemaAction.Add);
který sloučí data z dtMaster
pomocí dtSample
. false
param je to, co umožňuje příchozím změnám XML přepsat hodnoty v jiné tabulce (a případně je uložit do db).
Nemám ponětí, zda jsou některé problémy, jako jsou neodpovídající AI PK, velký problém nebo ne, ale zdá se, že to zvládne vše, co jsem našel. Ve skutečnosti se snažíte udělat Synchronizace databáze . Ačkoli s jednou tabulkou a jen několika řádky by výše uvedené mělo fungovat.