Najprostszym sposobem, który możesz chcieć, może być OBCIĄŻENIE tabeli docelowej, a następnie po prostu zapisanie w niej importu XML (z wyłączoną AI, aby w razie potrzeby używała zaimportowanego identyfikatora). Jedynym problemem mogą być prawa do tego. W przeciwnym razie...
To, co próbujesz zrobić, może prawie być obsługiwane za pomocą Merge
metoda. Jednak nie może/nie będzie wiedzieć o usuniętych wierszach. Ponieważ metoda działa na DataTables
, jeśli wiersz został usunięty z głównej bazy danych, po prostu nie będzie istniał w wyciągu XML (w przeciwieństwie do RowState
z Deleted
). Można je usunąć za pomocą pętli.
Podobnie, każdy nowy wiersz może otrzymać inne PK dla int AI. Aby temu zapobiec, po prostu użyj prostego pliku PK innego niż AI w docelowej bazie danych, aby mógł zaakceptować dowolną liczbę.
Ładowanie XML:
private DataTable LoadXMLToDT(string filename)
{
DataTable dt = new DataTable();
dt.ReadXml(filename);
return dt;
}
Kod scalający:
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 jakiegoś powodu rowsChanged
zawsze zgłasza tyle zmian, ile jest wszystkich wierszy. Ale zmiany z Master/XML DataTable przechodzą do innej/docelowej tabeli.
Kod usuwania pobiera listę istniejących identyfikatorów, a następnie określa, które wiersze należy usunąć z docelowej tabeli DataTable, określając, czy nowa tabela XML ma wiersz z tym identyfikatorem, czy nie. Wszystkie brakujące wiersze są usuwane, a następnie tabele są scalane.
Klucz to dtSample.Merge(dtMaster,false, MissingSchemaAction.Add);
która łączy dane z dtMaster
z dtSample
. false
parametr jest tym, co pozwala nadchodzącym zmianom XML nadpisać wartości w innej tabeli (i ostatecznie zapisać w bazie danych).
Nie mam pojęcia, czy niektóre problemy, takie jak niepasujące AI PK, to wielka sprawa, czy nie, ale wydaje się, że to wszystko, co udało mi się znaleźć. W rzeczywistości to, co próbujesz zrobić, to Synchronizacja bazy danych . Chociaż z jedną tabelą i tylko kilkoma rzędami, powyższe powinno działać.