windowsgm
windowsgm

Reputation: 1616

Copying Datatable Columns

I have the following method that returns a trimmed down copy of a datatable based on the user selecting which 6 columns to keep. My problem is the datatable can be quite large and is taking up quite a bit of memory. By creating the initial copy, this is causing the system to have to start writing to the page file and slowing the application down considerably.

I'm wondering if it is possible to create a datatable copy but of only the specified columns (can be identified through name or index, doesn't matter) rather than creating the copy then removing the unnecessary columns?

This question appears to be asking the same thing but in VB.net.

private DataTable CreateCleanData()
{
    var cleanedDataTable = _loadedDataData.Copy();
    var columnsToKeep = new List<string>();
    columnsToKeep.Add(1.SelectedValue.ToString());
    columnsToKeep.Add(2.SelectedValue.ToString());
    columnsToKeep.Add(3.SelectedValue.ToString());
    columnsToKeep.Add(4.SelectedValue.ToString());
    columnsToKeep.Add(5.SelectedValue.ToString());
    columnsToKeep.Add(6.SelectedValue.ToString());

    for (var i = cleanedDataTable.Columns.Count - 1; i >= 0; i--)
        if (!columnsToKeep.Contains(cleanedDataTable.Columns[i].ColumnName))
            cleanedDataTable.Columns.Remove(cleanedDataTable.Columns[i]);
    cleanedDatTable.AcceptChanges();
    GC.Collect();

    return cleanedDataTable;
}

Upvotes: 1

Views: 63

Answers (1)

Tim Schmelter
Tim Schmelter

Reputation: 460028

You could use this method, basically just use Clone instead of Copy:

public static DataTable CreateCleanData(DataTable source, params int[] keepColumns)
{
    var cleanedDataTable = source.Clone(); // empty table but same columns

    for (int i = cleanedDataTable.Columns.Count - 1; i >= 0; i--)
    {
        if (!keepColumns.Contains(i))
            cleanedDataTable.Columns.RemoveAt(i);
    }

    cleanedDataTable.BeginLoadData();
    foreach (DataRow sourceRow in source.Rows)
    {
        DataRow newRow = cleanedDataTable.Rows.Add();
        foreach (DataColumn c in cleanedDataTable.Columns)
        {
            newRow.SetField(c, sourceRow[c.ColumnName]);
        }
    }
    cleanedDataTable.EndLoadData();

    return cleanedDataTable;
}

Upvotes: 1

Related Questions