C #: преобразование DataTable строка за строкой - PullRequest
3 голосов
/ 20 июля 2010

В абстрактном классе ( C # 3 ) существует виртуальный метод с именем GetData, который возвращает DataTable. Алгоритм метода следующий:

  1. Получить строку SQL-запроса из класса.
  2. Получить DataTable из базы данных, используя вышеуказанный запрос.
  3. Выполнить преобразования в DataTable и вернуть его.

В 3-м пункте я клонирую исходную таблицу данных, чтобы изменить тип столбца (я не могу сделать это для заполненной таблицы и не могу установить это во 2-й точке) и перечисляю каждую строку, в которую я копирую и преобразовать данные из исходного. Преобразования зависят от класса, у каждого есть закрытые методы, которые самостоятельно преобразуют данные.

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

public delegate object Convert(object objectToConvert);

Преобразование будет выглядеть примерно так:

int rowCounter = 0;

foreach(DataRow row in dt.Rows)
{
 foreach(var item in Params)
 {
  row[item.ColumnIndex] = item.Convert(originalDataTable.Rows[rowCounter].ItemArray[item.ColumnIndex]);
 }

 ++rowCounter;
}

На данный момент я должен переопределить метод GetData() в каждом классе, в котором я хочу иметь преобразования, которые вызывают большое дублирование кода. Цель, которую я хочу достичь, - создать базовый класс, который будет основан на параметрах, которые я упомянул выше. Вышеупомянутое решение хорошо для этой проблемы, или это любой другой способ сделать это?

Ответы [ 2 ]

1 голос
/ 03 августа 2010

Хорошо, сейчас у меня есть следующее решение, которое полностью удовлетворяет меня:

Каждый преобразователь реализует следующий интерфейс:

public interface IConvertor
{
 object Convert(object item);
}

Параметры следующие::

Type ColumnType { get; protected set; } // New type
string[] ColumnNames { get; protected set; }
IConvertor Convertor { get; protected set; }

Каждый объект имеет свое собственное Params свойство массива.У меня есть один метод для каждого производного класса, и все, что мне нужно сделать, это настроить параметры.

1 голос
/ 20 июля 2010

Во-первых, я не большой поклонник DataTable, вместо этого вы можете использовать DataReader, если вы делаете foreach.

using (var dataReader = ....)
    {
         while(dataReader.Read())
         {
             foreach(var item in Params)
             {
                  row[item.ColumnIndex] = item.Convert(originalDataTable.Rows[rowCounter].ItemArray[item.ColumnIndex]);
             }
         }
    }

Во-вторых, создайте базовый класс с абстрактным методом с некоторым кодом и внесите объект в список. Params наследует этот класс и переопределяет метод только в случае необходимости.

public class MyClass
{
      public abstract object Convert(DataRow row)
      {
      ....
      }
}

public class foo : MyClass
{
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...