ehh
ehh

Reputation: 3480

Make a copy of a Datatable with some changes

I am trying to make a copy of a DataTable dt1 to a new one dt2. dt1 contains columns of string and boolean types. dt2 will contains only string types.

The following is my code which works fine.

    public DataTable Convert(DataTable dt1)
    {
        try
        {
            var dt2 = dt1.Clone();
            foreach (DataColumn dc in dt2.Columns)
            {
                dc.DataType = Type.GetType("System.String");
            }

            foreach (DataRow row in dt1.Rows)
            {
                dt2.ImportRow(row);
            }

            foreach (DataRow dr in dt2.Rows)
            {
                foreach (DataColumn dc in dt2.Columns)
                {
                    bool value;
                    if (bool.TryParse(dr[dc].ToString(), out value))
                    {
                        dr[dc] = "+";
                    }
                }
            }

            return dt2;
        }
        finally
        {

        }
    }

Is there a better way to perform those steps. "better" mean clearer, simpler, less code, less steps, better performance.

Upvotes: 0

Views: 1318

Answers (2)

Lee Hiles
Lee Hiles

Reputation: 1135

The code you've provided very clearly describes your intent and is succinct. We can however make some optimizations that will help with performance.

  1. You are attempting to parse every field of every row instead of determining which fields actually require manipulation. As the number of non-boolean columns increases you're doing more work than is needed.
  2. You already have the original table which contains bool values so you could do away with parsing all together.

Here is a version that optimizes around these two points. The code is not shorter or more elegant, but it will require no text parsing and far fewer evaluations.

public DataTable Convert2(DataTable dt1)
{
    DataTable dt2 = dt1.Clone();

    // Alter all columns datatype
    foreach (DataColumn col in dt2.Columns)
        col.DataType = typeof(string);

    // Import all rows from existing table
    foreach (DataRow row in dt1.Rows)
        dt2.ImportRow(row);

    // Index the boolean columns that will require evaluation
    List<int> booleans = new List<int>();
    foreach (DataColumn col in dt1.Columns)
    {
        if (col.DataType == typeof(bool))
            booleans.Add(col.Ordinal);
    }

    // Since two tables will be identical except for datatypes 
    // iterate over original table and cast instead of performing
    // a string conversion and parsing the result.
    for (int row = 0; row < dt1.Rows.Count; row++)
    {
        foreach (int index in booleans)
        {
            if ((bool) dt1.Rows[row][index])
                dt2.Rows[row][index] = "+";
        }
    }

    return dt2;
}

Additionally, I left out the try..finally block since you're not using it.

Upvotes: 1

Mr_Thorynque
Mr_Thorynque

Reputation: 2002

That code would do the job.

public DataTable Convert(DataTable dt1)
{
    try
    {
        var dt2 = dt1.Clone();
        foreach (DataColumn dc in dt2.Columns)
        {
            dc.DataType = Type.GetType("System.String");
        }

        foreach (DataRow row in dt1.Rows)
        {
            dt2.ImportRow(row);
            DataRow dr = dt2.Rows[dt2.Rows.Count-1]
            foreach (DataColumn dc in dt2.Columns)
            {
                bool value;
                if (bool.TryParse(dr[dc].ToString(), out value))
                {
                    dr[dc] = "+";
                }
            }
        }

        return dt2;
    }
    finally
    {

    }
}

Upvotes: 1

Related Questions