2016-03-30 2 views
0

Я пытаюсь сделать копию DataTable dt1 новым dt2. dt1 содержит столбцы типа string и boolean. dt2 будет содержать только типы строк.Сделайте копию Datatable с некоторыми изменениями

Следующий мой код, который отлично работает.

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 
     { 

     } 
    } 
  • первый шаг: Клон dt1 и изменить типы столбцов в строке.
  • второй шаг: Импорт строки из dt1 в dT2
  • 3-й шаг: Измените все истинные значения «+»

Есть ли лучший способ для выполнения этих шагов. «лучше» означает более четкое, простое, меньшее количество кода, меньшее количество шагов и лучшую производительность.

+0

У вас есть проблема с производительностью? Вы можете попробовать реализовать только один цикл над строками, импортировать строку и обновить ее после. Но оба типа данных имеют одинаковую структуру, поэтому, возможно, лучше создать новую строку и скопировать поле, если вам не нужно состояние или что-то еще. –

+0

Мне было интересно, есть ли другое решение вместо того, чтобы дважды зацикливать на строки и дважды на столбцы – ehh

ответ

1

Код, который вы предоставили, очень четко описывает ваши намерения и является кратким. Однако мы можем сделать некоторые оптимизации, которые помогут в производительности.

  1. Вы пытаетесь разобрать каждое поле каждой строки, а не определять, какие поля требуют манипулирования. По мере увеличения количества небулевых столбцов вы делаете больше работы, чем нужно.
  2. У вас уже есть оригинальная таблица, которая содержит значения bool, чтобы вы могли покончить с синтаксическим разбором.

Вот версия, которая оптимизируется вокруг этих двух точек. Код не короче или более изящный, но для него не требуется синтаксический анализ текста и гораздо меньше оценок.

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; 
} 

Кроме того, я ушел из try..finally блока, так как вы не используете.

1

Этот код выполнит эту работу.

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 
    { 

    } 
} 
Смежные вопросы