2012-12-27 8 views
9

मैं एक लघु एल्गोरिदम लिख रहा हूं जिसे दो डेटासेट की तुलना करना है, ताकि दोनों के बीच अंतर को और संसाधित किया जा सके। मैंने इन दो डेटासेट्स को विलय करके इस परिणाम को पूरा करने का प्रयास किया और परिणामी परिवर्तनों को एक नए डेटासेट में प्राप्त किया।2 डेटासेट्स में अंतर प्राप्त करें C#

मेरे विधि इस प्रकार है:

private DataSet ComputateDiff(DataSet newVersion, DataSet oldVersion) 
    { 
     DataSet diff = null; 
     oldVersion.Merge(newVersion); 
     bool foundChanges = oldVersion.HasChanges(); 
     if (foundChanges) 
     { 
      diff = oldVersion.GetChanges(); 
     } 
     return diff; 
    } 

foundChanges का परिणाम हमेशा गलत है, भले ही दोनों डेटासेट उस में अलग-अलग मान। दोनों डेटासेट्स में एक ही strukture है। उनमें तीन डेटाटेबल्स शामिल हैं जो डेटाबेस में तीन क्वेरी का परिणाम हैं। मर्ज उस के साथ कोई समस्या ठीक काम करता है।

मेरा प्रश्न है: कोई उचित स्पष्टीकरण क्यों foundChanges चर हमेशा गलत है और है नहीं तो Linq इस समस्या के लिए एक उचित समाधान प्रदान करते हैं या मैं डेटा सेट में पुनरावृत्ति द्वारा परिवर्तन निर्धारित करने के लिए है क्या करना होगा

यहां कुछ और जानकारी दी गई हैं: प्रोग्रामिंग भाषा सी # है। मैं नेट फ्रेमवर्क 4.0 का उपयोग कर रहा हूं। मैं विंडोज 8 मशीन पर विकसित कर रहा हूं जैसा कि बताया गया डेटा डेटाबेस (एमएसएसक्यूएल सर्वर 2012 एक्सप्रेस) से आता है मेरा डेटासेट या डेटाटेबल्स हेवन जहां तक ​​मुझे पता है कि कोई पीके है।

अग्रिम धन्यवाद

+1

आमतौर पर आप जो करना चाहते हैं वह एक डेटासेट पुराना संस्करण लेता है और इसे संशोधित करता है। फिर पुराने संस्करण में सभी नए बदलाव होंगे। फिर आप डेटासेट diff = oldVersion.GetChanges() को कॉल कर सकते हैं। –

+1

आपको यह उपयोगी मिल सकता है: http://stackoverflow.com/a/7518025/211627 – JDB

उत्तर

3

में मुझे लगता है कि समस्या यह है कि आप नेट डेटासेट समझ में नहीं आता है। डेटाटेबल इसमें लोड किए गए प्रत्येक मान की "मूल" प्रति को बरकरार रखता है। जब कोई मान बदल जाता है, तो डेटाटेबल परिवर्तन का पता लगाने में सक्षम होता है। इसी तरह, डेटाटेबल उन पंक्तियों का ट्रैक रखता है जिन्हें जोड़ा या हटा दिया गया है। HasChanges() समारोह बस DataTables और चेक के माध्यम से क्रॉल करता है यह देखने के लिए कि क्या कोई परिवर्तन (बदला मूल्य, नई पंक्तियाँ, नष्ट कर दिया पंक्तियों, आदि)

MSDN दस्तावेज़ देखें हो गया है:
http://msdn.microsoft.com/en-us/library/system.data.dataset.haschanges.aspx

दोनों डेटासेट है की तुलना करना मुश्किल, और मुझे इसे संभालने के लिए किसी अंतर्निहित फ़ंक्शन से अवगत नहीं है (क्योंकि प्रत्येक प्रोग्रामर की "समतुल्यता" की अपनी परिभाषा होगी)।

देखें:

कोड के नीचे जोड़ा/नष्ट कर दिया एक कुंजी स्तंभ के आधार पर पंक्तियों की तलाश द्वारा दो DataTables तुलना और संशोधित होगा पंक्तियों से मेल खाने वाली पंक्तियों के मूल्यों की तुलना करना (फिर से, कुंजी के आधार पर)। डेटासेट्स की तुलना करने के लिए इसे विस्तारित करना काफी मुश्किल होगा (डेटासेट के बीच समान नामित तालिकाओं की तुलना करके)।

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Data; 

namespace DataSetComparison 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 

      var l_table1 = new DataTable(); 
      l_table1.Columns.Add("Key", typeof(int)); 
      l_table1.Columns.Add("Name", typeof(string)); 
      l_table1.Columns.Add("Age", typeof(int)); 

      var l_table2 = new DataTable(); 
      l_table2.Columns.Add("Key", typeof(int)); 
      l_table2.Columns.Add("Name", typeof(string)); 
      l_table2.Columns.Add("Age", typeof(int)); 

      l_table1.Rows.Add(l_table1.NewRow()); 
      l_table1.Rows[l_table1.Rows.Count - 1]["Key"] = 0; 
      l_table1.Rows[l_table1.Rows.Count - 1]["Name"] = "Alfred Harisson"; 
      l_table1.Rows[l_table1.Rows.Count - 1]["Age"] = 36; 
      l_table1.Rows.Add(l_table1.NewRow()); 
      l_table1.Rows[l_table1.Rows.Count - 1]["Key"] = 1; 
      l_table1.Rows[l_table1.Rows.Count - 1]["Name"] = "Matthew George"; 
      l_table1.Rows[l_table1.Rows.Count - 1]["Age"] = 41; 
      l_table1.Rows.Add(l_table1.NewRow()); 
      l_table1.Rows[l_table1.Rows.Count - 1]["Key"] = 2; 
      l_table1.Rows[l_table1.Rows.Count - 1]["Name"] = "Franklin Henry"; 
      l_table1.Rows[l_table1.Rows.Count - 1]["Age"] = 33; 

      l_table2.Rows.Add(l_table2.NewRow()); 
      l_table2.Rows[l_table2.Rows.Count - 1]["Key"] = 0; 
      l_table2.Rows[l_table2.Rows.Count - 1]["Name"] = "Alfred Harisson"; 
      l_table2.Rows[l_table2.Rows.Count - 1]["Age"] = 36; 
      l_table2.Rows.Add(l_table2.NewRow()); 
      l_table2.Rows[l_table2.Rows.Count - 1]["Key"] = 1; 
      l_table2.Rows[l_table2.Rows.Count - 1]["Name"] = "Matthew George"; 
      l_table2.Rows[l_table2.Rows.Count - 1]["Age"] = 42; // Record 1 "modified" 
      // Record 2 "deleted" 
      // Record 3 "added": 
      l_table2.Rows.Add(l_table2.NewRow()); 
      l_table2.Rows[l_table2.Rows.Count - 1]["Key"] = 3; 
      l_table2.Rows[l_table2.Rows.Count - 1]["Name"] = "Lester Kulick"; 
      l_table2.Rows[l_table2.Rows.Count - 1]["Age"] = 33; 

      // Using table 1 as the control, find changes in table 2 

      // Find deleted rows: 
      var l_table2Keys = l_table2.Select().Select((r) => (int) r["Key"]); 
      var l_deletedRows = l_table1.Select().Where((r) => !l_table2Keys.Contains((int) r["Key"])); 

      foreach (var l_deletedRow in l_deletedRows) 
       Console.WriteLine("Record " + l_deletedRow["Key"].ToString() + " was deleted from table 2."); 

      // Find added rows: 
      var l_table1Keys = l_table1.Select().Select((r) => (int) r["Key"]); 
      var l_addedRows = l_table2.Select().Where((r) => !l_table1Keys.Contains((int) r["Key"])); 

      foreach (var l_addedRow in l_addedRows) 
       Console.WriteLine("Record " + l_addedRow["Key"].ToString() + " was added to table 2."); 

      // Find modified rows: 
      var l_modifiedRows = l_table2.Select() 
             .Join(
              l_table1.Select(), 
              r => (int) r["Key"], 
              r => (int) r["Key"], 
              (r1, r2) => new 
               { 
                Row1 = r1, 
                Row2 = r2 
               }) 
             .Where(
              values => !(values.Row1["Name"].Equals(values.Row2["Name"]) && 
                 values.Row1["Age"].Equals(values.Row2["Age"]))) 
             .Select(values => values.Row2); 

      foreach (var l_modifiedRow in l_modifiedRows) 
       Console.WriteLine("Record " + l_modifiedRow["Key"].ToString() + " was modified in table 2."); 

      Console.WriteLine("Press any key to quit..."); 
      Console.ReadKey(true); 

     } 
    } 
} 

कंसोल आउटपुट:

रिकार्ड 2 टेबल से हटा दिया गया 2.
रिकार्ड 3 तालिका 2.
रिकार्ड 1 में जोड़ा गया था तालिका 2 में संशोधित किया गया था।

+0

बस देखे जा रहे हैं। कंटेनर, .exists आपके लिए उपयोगी हो सकते हैं। –

+0

साइबोर्गक्स 37 सही है आप आसानी से ऐसा नहीं कर सकते हैं। आपको डेटासेट की चाबियों का ज्ञान होना चाहिए, अन्यथा आप यह बताने में सक्षम नहीं होंगे कि कोई परिवर्तन एक अपडेट, डिलीट या डालने वाला है या नहीं। –

0

दोनों डेटासेट के स्कीमा एक ही हैं तो आप एक

Dataset dsTest1 
DataSet dsTest2 
DataSet dsFinal; 
dsFinal.Merge(dsTest1); 
dsFinal.AcceptChanges(); 
dsFinal.Merge(dsTest2); 
DifferenceDataSet = dsFinal.GetChanges() 

नीचे कोशिश कर सकते हैं दोनों डेटासेट के स्कीमा तो अलग हैं आप इसे मैन्युअल रूप से करना है तो।

+0

मैं लोगों को यह क्यों कहता रहता हूं कि मर्ज + गेट चेंज काम करता है, जब ऐसा नहीं होता है? –

-1

जैसा कि आप कुछ अन्य उत्तरों से देख सकते हैं, दो डेटासेटों का अंतर प्राप्त करना आसान नहीं है।

यह डेटासेट.गेट चेंज() का उद्देश्य है। यदि आप किसी डेटासेट से प्रारंभ करते हैं और सीधे उस डेटासेट में परिवर्तन करते हैं (यानी जब कोई उपयोगकर्ता सेल को अपडेट करता है, जब कोई उपयोगकर्ता कोई फॉर्म सबमिट करता है, आदि ...) तो डेटासेट परिवर्तनों को ट्रैक करता है। इस तरह आप परिवर्तन (या अंतर) प्राप्त करने के लिए DataSet.GetChanges() को कॉल कर सकते हैं। फिर आप केवल परिवर्तनों को संसाधित कर सकते हैं।

प्रारंभिक डेटासेट और अंतिम डेटासेट लेने और अंतर प्राप्त करने में एक कठिन समस्या है। पुराने डेटासेट के साथ अंतिम डेटासेट को विलय करना भी समझ में नहीं आता है, क्योंकि अंतिम डेटासेट मर्ज का परिणाम है।

संबंधित मुद्दे