2010-07-02 6 views
2

J'ai un datatable avec 17 colonnes et un tas de données.Sous-ensemble de colonnes datable d'un autre datable

I wnat une datatable avec seulement 6 des colonnes et les données pour ces 6 colonnes.

J'ai donc besoin d'un sous-ensemble du datatable original.

Comment est-ce que je boucle la datatable originale avec 17 colonnes et finis avec un datatable avec seulement 6 colonnes que je veux avec les données correspondantes pour ces 6 colonnes?

+0

Comment êtes-vous d'abord datatable peuplant? Si vous le remplissez à partir d'une base de données, il devrait être facile à faire comme vous le demandez via les commandes SQL SELECT. –

Répondre

2

sans en savoir plus sur la façon dont cela doit être générique est vraiment juste ...

foreach (DataRow dr in dt.Rows) 
{ 
    newDt.Rows.Add(dr["col1"],dr["col5"],etc); 
} 
+0

Je crois qu'il y a une faute de frappe ici - vous voulez dt.Rows ["col5"], pas dr, n'est-ce pas? Ou, alternativement, vous pourriez avoir dr ["col1"], dr ["col5"] ... – Melanie

+0

@Melanie Oui, je pense que le dernier est correct et ce que je pensais quand j'ai écrit ceci (bien qu'il y a trois ans et Je ne me souviens vraiment pas avoir répondu à tout ça haha) ... édité ma réponse pour refléter votre correction – heisenberg

0

qu'en est-il des types de données et des colonnes? sont-ils pareils? Si oui, vous pouvez créer

object[] row = new object[]{// Fill your rows manually}; 

avant de le remplir de créer

DataTable dt = new DataTable(); 
dt.Columns.Add("Title",typeof(string etc..));..... 

et enfin

dt.Rows.Add(row); 
0

Personnellement, je voudrais évitez de créer une autre instance d'un DataTable. Cela dépend de votre situation, bien sûr, mais si c'est uniquement pour la facilité d'utilisation et non pour la sécurité (vous n'essayez pas de supprimer des colonnes avec des données sensibles avant de les transmettre quelque part), je crée un objet wrapper qui encapsule les colonnes que vous souhaitez exposer. L'avantage d'utiliser un wrapper est au cas où vous faites des mises à jour, alors vous pouvez mettre à jour la table source directement plutôt que la copie. Que cela compte vraiment, bien sûr, dépend de votre situation.

Un exemple simple avec des fonctionnalités limitées:

public class MyFormOrPage 
{ 
    void UsageExample() 
    { 
     DataTable allDataTable = new DataTable(); 
     // populate the data table with whatever logic ... 

     // wrap the data table to expose only the Name, Address, and PhoneNumber columns 
     var limitedDataTable = new DataTableWrapper(allDataTable, "Name", "Address", "PhoneNumber"); 

     // iterate over the rows 
     foreach (var limitedDataRow in limitedDataTable) 
     { 
      // iterate over the columns 
      for (int i = 0; i < limitedDataTable.ColumnCount; i++) 
      { 
       object value = limitedDataRow[i]; 
       // do something with the value ... 
      } 
     } 

     // bind the wrapper to a control 
     MyGridControl.DataSource = limitedDataTable; 
    } 
} 

public class DataTableWrapper : IEnumerable<DataRowWrapper> 
{ 
    private DataTable _Table; 

    private string[] _ColumnNames; 

    public DataTableWrapper(DataTable table, params string[] columnNames) 
    { 
     this._Table = table; 

     this._ColumnNames = columnNames; 
    } 

    public int ColumnCount 
    { 
     get { return this._ColumnNames.Length; } 
    } 

    public IEnumerator<DataRowWrapper> GetEnumerator() 
    { 
     foreach (DataRow row in this._Table.Rows) 
     { 
      yield return new DataRowWrapper(row, this._ColumnNames); 
     } 
    } 

    #region IEnumerable Members 

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 
     return this.GetEnumerator(); 
    } 

    #endregion 

    // if you _really_ want to make a copy of the DataTable, you can use this method 
    public DataTable CopyToDataTable() 
    { 
     DataTable copyTable = new DataTable(); 
     for (int index = 0; index < this._ColumnNames.Length; index++) 
     { 
      DataColumn column = this._Table.Columns[index]; 
      copyTable.Columns.Add(column); 
     } 
     foreach (DataRow row in this._Table.Rows) 
     { 
      DataRow copyRow = copyTable.NewRow(); 
      for (int index = 0; index < this._ColumnNames.Length; index++) 
      { 
       copyRow[index] = row[this._ColumnNames[index]]; 
      } 
      copyTable.Rows.Add(copyRow); 
     } 
     return copyTable; 
    } 
} 

// let's make this a struct, since potentially very many of these will be instantiated 
public struct DataRowWrapper 
{ 
    private DataRow _Row; 

    private string[] _ColumnNames; 

    public DataRowWrapper(DataRow row, params string[] columnNames) 
    { 
     this._Row = row; 

     this._ColumnNames = columnNames; 
    } 

    // use this to retrieve column values from a row 
    public object this[int index] 
    { 
     get { return this._Row[this._ColumnNames[index]]; } 
     set { this._Row[this._ColumnNames[index]] = value; } 
    } 

    // just in case this is still needed... 
    public object this[string columnName] 
    { 
     get { return this._Row[columnName]; } 
     set { this._Row[columnName] = value; } 
    } 
} 
2
Private Function createSmallCopyofExistingTable(ByVal SourceTable As DataTable) As DataTable 
    Dim newTable As DataTable = New DataTable() 

    'Copy Only 6 columns from the datatable 
    Dim ColumnsToExport() As String = {"ID", "FirstName", "LastName", "DateOfBirth", "City", "State"} 

    newTable = SourceTable.DefaultView.ToTable("tempTableName", False, ColumnsToExport) 



    Return newTable 
End Function