Cara paling sederhana yang mungkin ingin Anda lihat adalah dengan MEMOTONG tabel tujuan, lalu cukup simpan impor XML ke dalamnya (dengan AI mati sehingga menggunakan ID yang diimpor jika perlu). Satu-satunya masalah mungkin dengan hak untuk melakukan itu. Jika tidak...
Apa yang Anda coba lakukan dapat hampir ditangani menggunakan Merge
metode. Namun, itu tidak dapat/tidak akan mengetahui tentang baris yang dihapus. Karena metode ini bekerja pada DataTables
, jika sebuah baris dihapus dalam database master, baris tersebut tidak akan ada dalam ekstrak XML (dibandingkan dengan RowState
dari Deleted
). Ini dapat disingkirkan dengan satu putaran.
Demikian juga, setiap baris baru mungkin mendapatkan PK yang berbeda untuk int AI. Untuk mencegahnya, cukup gunakan PK non-AI sederhana di db tujuan sehingga dapat menerima nomor apa pun.
Pemuatan XML:
private DataTable LoadXMLToDT(string filename)
{
DataTable dt = new DataTable();
dt.ReadXml(filename);
return dt;
}
Kode gabungan:
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);
}
Untuk alasan apa pun, rowsChanged
selalu melaporkan perubahan sebanyak jumlah baris. Namun perubahan dari Master/XML DataTable mengalir ke tabel lain/tujuan.
Kode hapus mendapatkan daftar ID yang ada, lalu menentukan baris mana yang perlu dihapus dari DataTable tujuan dengan apakah tabel XML baru memiliki baris dengan ID tersebut atau tidak. Semua baris yang hilang dihapus, lalu tabel digabungkan.
Kuncinya adalah dtSample.Merge(dtMaster,false, MissingSchemaAction.Add);
yang menggabungkan data dari dtMaster
dengan dtSample
. false
param adalah apa yang memungkinkan perubahan XML yang masuk untuk menimpa nilai di tabel lain (dan akhirnya disimpan ke db).
Saya tidak tahu apakah beberapa masalah seperti AI PK yang tidak cocok adalah masalah besar atau tidak, tetapi ini tampaknya menangani semua yang dapat saya temukan. Pada kenyataannya, apa yang Anda coba lakukan adalah Sinkronisasi Basis Data . Meskipun dengan satu tabel, dan hanya beberapa baris, hal di atas akan berfungsi.