सबसे आसान तरीका जिसे आप देखना चाहते हैं, वह हो सकता है कि गंतव्य तालिका को TRUNCATE करें, फिर बस XML आयात को इसमें सहेजें (एआई बंद के साथ, यदि आवश्यक हो तो यह आयातित आईडी का उपयोग करता है)। ऐसा करने के अधिकारों के साथ एकमात्र समस्या हो सकती है। वरना...
आप जो करने का प्रयास कर रहे हैं वह लगभग हो सकता है Merge
. का उपयोग करके संभाला जा सकता है तरीका। हालांकि, यह हटाई गई पंक्तियों के बारे में नहीं जान सकता/नहीं जानता। चूंकि यह विधि DataTables
. पर कार्य कर रही है , अगर मास्टर डेटाबेस में एक पंक्ति हटा दी गई थी, तो यह एक्सएमएल निकालने में मौजूद नहीं होगी (बनाम एक RowState
का Deleted
) इन्हें लूप से निकाला जा सकता है।
इसी तरह, किसी भी नई पंक्तियों को एआई इंट के लिए एक अलग पीके मिल सकता है। इसे रोकने के लिए, गंतव्य डीबी में एक साधारण गैर-एआई पीके का उपयोग करें ताकि यह किसी भी संख्या को स्वीकार कर सके।
एक्सएमएल लोड हो रहा है:
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
हमेशा उतने ही परिवर्तनों की रिपोर्ट करता है, जितने कुल पंक्तियाँ हैं। लेकिन मास्टर/एक्सएमएल डेटाटेबल से परिवर्तन अन्य/गंतव्य तालिका में प्रवाहित होते हैं।
डिलीट कोड को मौजूदा आईडी की एक सूची मिलती है, फिर यह निर्धारित करता है कि नई एक्सएमएल तालिका में उस आईडी के साथ एक पंक्ति है या नहीं, यह निर्धारित करता है कि गंतव्य डेटाटेबल से किन पंक्तियों को हटाने की आवश्यकता है। सभी अनुपलब्ध पंक्तियाँ हटा दी जाती हैं, फिर तालिकाएँ मर्ज कर दी जाती हैं।
कुंजी है dtSample.Merge(dtMaster,false, MissingSchemaAction.Add);
जो dtMaster
. से डेटा मर्ज करता है dtSample
. के साथ . false
परम वह है जो आने वाले एक्सएमएल परिवर्तनों को अन्य तालिका में मूल्यों को ओवरराइट करने की अनुमति देता है (और अंततः डीबी में सहेजा जाता है)।
मुझे नहीं पता कि गैर मिलान वाले एआई पीके जैसे कुछ मुद्दे एक बड़ी बात है या नहीं, लेकिन ऐसा लगता है कि मुझे जो कुछ मिल सकता है उसे संभालना है। वास्तव में, आप जो करने की कोशिश कर रहे हैं वह है डेटाबेस सिंक्रोनाइजेशनए> . हालांकि एक टेबल और बस कुछ पंक्तियों के साथ, उपरोक्त काम करना चाहिए।