2012-05-08 12 views
5

मैं दो DataTables इस सवाल का एक समान तरीके से एक साथ शामिल होने के लिए कोशिश कर रहा हूँ गतिशील कॉलम के साथ शामिल हो 'टेबल, दोनों मूल सारणी से कॉलम के साथ। वे दोनों में एक डेटास्टैम्प कॉलम सामान्य होगा।सी # DataTable इनर

दिए गए उत्तर निश्चित कॉलम के साथ डेटाटेबल्स के लिए अच्छा है, लेकिन अगर वे गतिशील रूप से बनाए जाते हैं, और उनमें कोई भी कॉलम हो सकता है, तो मैं उनसे कैसे जुड़ सकता हूं?

उदा।

T1 (datestamp, t1Column1, t1Column2, t1ColumnN...) 
T2 (datestamp, t2Column1, t2Column2, t2ColumnN...) 

मैं में शामिल होने के लिए करना चाहते हैं बनाने के लिए निम्नलिखित:

J1 (datestamp, t1Column1, t1Column2, t1ColumnN, ..., t2Column1, t2Column2, t2ColumnN...) 

यह संभव है?

+0

क्या आप "linq" का उपयोग कर सकते हैं? –

+0

क्या आप कुछ डेटा का उदाहरण दे सकते हैं जो परिणाम आप चाहते हैं? –

+0

मुझे नहीं लगता कि लिंक एक विकल्प है क्योंकि आपको उस कॉलम नामों को जानना होगा जिन्हें आप प्रोजेक्ट करने का प्रयास कर रहे थे। – finoutlook

उत्तर

7

मैं एक समाधान है जो कॉलम के माध्यम से पाशन पर निर्भर नहीं करता पाया: या आप सिर्फ इस तरह प्रत्येक पंक्ति में आइटम, के माध्यम से लूप सकता है।

यह 'मर्ज' विधि का उपयोग करता है, जिसे मैंने पहले खारिज कर दिया था क्योंकि मैंने सोचा था कि दोनों टेबलों को एक ही संरचना की आवश्यकता है। जोड़ा जा सकता है

// set primary key 
T1.PrimaryKey = new DataColumn[] { T1.Columns["DateStamp"] }; 
T2.PrimaryKey = new DataColumn[] { T2.Columns["DateStamp"] }; 

फिर एक डेटा-सेट तो एक रिश्ता करने के लिए दोनों तालिकाओं जोड़ें::

// add both data-tables to data-set 
DataSet dsContainer = new DataSet(); 
dsContainer.Tables.Add(T1); 
dsContainer.Tables.Add(T2); 

अगला

सबसे पहले आपको दो डेटा-टेबल पर एक प्राथमिक कुंजी बनाने की जरूरत डेटा-सेट में दो प्रमुख कॉलम के बीच संबंध जोड़ें:

// add a relationship between the two timestamp columns 
DataRelation relDateStamp = new DataRelation("Date", new DataColumn[] { T1.Columns["DateStamp"] }, new DataColumn[] { T2.Columns["DateStamp"] }); 
dsContainer.Relations.Add(relDateStamp); 

अंत में आप पहले कॉपी कर सकते हैं एक नए 'संयुक्त' संस्करण में डेटा की मेज, और फिर दूसरे में विलय:

// populate combined data 
DataTable dtCombined = new DataTable(); 
dtCombined = T1.Copy(); 
dtCombined.Merge(T2, false, MissingSchemaAction.Add); 

नोट: मर्ज विधि दूसरा तर्क वरना आवश्यकता है गलत यह प्रतियां संरचना लेकिन दूसरे की नहीं डेटा तालिका।एक संयुक्त संस्करण प्राथमिक कुंजी के आधार पर में

T1 (2012-05-09, 111, 222) 
T2 (2012-05-09, 333, 444, 555) 

:

यह तो गठबंधन होगा निम्न तालिकाओं

J1 (2012-05-09, 111, 222, 333, 444, 555) 
1

मुझे लगता है कि आप कॉलम नाम के बजाय index of the column का उपयोग करने के लिए लिंक किए गए प्रश्न में उत्तर को अनुकूलित कर सकते हैं।

foreach(DataRow row in table.Rows) 
{ 
    foreach(DataColumn column in table.Columns) 
    { 
     object value = row[column]; // add this to your combined table 
    } 
} 
+0

धन्यवाद - मैं सभी कॉलम के माध्यम से लूपिंग से बचने की उम्मीद कर रहा था क्योंकि मेरे पास मूल सारणी सेट करने के लिए पहले से ही कुछ नेस्टेड लूप हैं। यदि टेबल में डेटा की कई अलग-अलग तिथियां/कुंजी हैं तो यह काफी जटिल हो सकता है। – finoutlook

1

देखकर थक मिलने के बाद इन सभी आंतरिक कार्यों में शामिल होने कि डॉन ' टी विश्वसनीय रूप से अनुकरण एसक्यूएल, मैंने अपना खुद का यहां बनाने का फैसला किया:

private DataTable JoinDataTables(DataTable t1, DataTable t2, params Func<DataRow, DataRow, bool>[] joinOn) 
{ 
    DataTable result = new DataTable(); 
    foreach (DataColumn col in t1.Columns) 
    { 
     if (result.Columns[col.ColumnName] == null) 
      result.Columns.Add(col.ColumnName, col.DataType); 
    } 
    foreach (DataColumn col in t2.Columns) 
    { 
     if (result.Columns[col.ColumnName] == null) 
      result.Columns.Add(col.ColumnName, col.DataType); 
    } 
    foreach (DataRow row1 in t1.Rows) 
    { 
     var joinRows = t2.AsEnumerable().Where(row2 => 
      { 
       foreach (var parameter in joinOn) 
       { 
        if (!parameter(row1, row2)) return false; 
       } 
       return true; 
      }); 
     foreach (DataRow fromRow in joinRows) 
     { 
      DataRow insertRow = result.NewRow(); 
      foreach (DataColumn col1 in t1.Columns) 
      { 
       insertRow[col1.ColumnName] = row1[col1.ColumnName]; 
      } 
      foreach (DataColumn col2 in t2.Columns) 
      { 
       insertRow[col2.ColumnName] = fromRow[col2.ColumnName]; 
      } 
      result.Rows.Add(insertRow); 
     } 
    } 
    return result; 
} 

एक परीक्षा आप इसका उपयोग कैसे कर सकते हैं:

var test = JoinDataTables(transactionInfo, transactionItems, 
       (row1, row2) => 
       row1.Field<int>("TransactionID") == row2.Field<int>("TransactionID")); 
+0

अच्छी तरह से किया। क्या कई "शर्तों पर" स्थितियों के बीच एक AND या OR ऑपरेटर निर्दिष्ट करने में सक्षम होने के लिए इसे संशोधित करने का कोई तरीका है? – Igor