Cách đơn giản nhất mà bạn có thể muốn xem xét có thể là TRUNCATE bảng đích, sau đó chỉ cần lưu nhập XML vào đó (tắt AI để nó sử dụng ID đã nhập nếu cần). Vấn đề duy nhất có thể là với quyền để làm điều đó. Nếu không ...
Những gì bạn đang cố gắng làm có thể hầu như được xử lý bằng cách sử dụng Merge
phương pháp. Tuy nhiên, nó không thể / sẽ không biết về hàng đã xóa. Vì phương thức đang hoạt động trên DataTables
, nếu một hàng đã bị xóa trong cơ sở dữ liệu chính, nó sẽ đơn giản không tồn tại trong phần trích xuất XML (so với một RowState
trong tổng số Deleted
). Chúng có thể được loại bỏ bằng một vòng lặp.
Tương tự như vậy, bất kỳ hàng mới nào cũng có thể nhận được một PK khác cho một int AI. Để tránh điều đó, chỉ cần sử dụng PK đơn giản không phải AI trong db đích để nó có thể chấp nhận bất kỳ số nào.
Tải XML:
private DataTable LoadXMLToDT(string filename)
{
DataTable dt = new DataTable();
dt.ReadXml(filename);
return dt;
}
Mã hợp nhất:
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);
}
Vì bất kỳ lý do gì, rowsChanged
luôn báo cáo nhiều thay đổi vì có tổng số hàng. Nhưng những thay đổi từ Master / XML DataTable thực hiện luồng qua bảng kia / đích.
Mã xóa nhận danh sách các ID hiện có, sau đó xác định hàng nào cần được xóa khỏi DataTable đích bằng cách xem bảng XML mới có hàng có ID đó hay không. Tất cả các hàng bị thiếu sẽ bị xóa, sau đó các bảng được hợp nhất.
Khóa là dtSample.Merge(dtMaster,false, MissingSchemaAction.Add);
hợp nhất dữ liệu từ dtMaster
với dtSample
. false
param là thứ cho phép các thay đổi XML đến ghi đè các giá trị trong bảng khác (và cuối cùng được lưu vào db).
Tôi không biết liệu một số vấn đề như PK AI không khớp có phải là vấn đề lớn hay không, nhưng điều này dường như xử lý tất cả những gì tôi có thể tìm thấy. Trên thực tế, những gì bạn đang cố gắng làm là Đồng bộ hóa cơ sở dữ liệu . Mặc dù với một bảng và chỉ một vài hàng, những điều trên sẽ hoạt động.