Herman<T>.Instance Ответов: 3

изменение типа данных объекта datatable в языке c#


Как изменить тип данных datatbale в c#, уже имея данные внутри.
У меня есть поле int, которое должно быть typeof(string)

3 Ответов

Рейтинг:
6

WaseemAmin

Если вы хотите преобразовать тип всех или некоторых столбцов в один тип, например, строковый тип, то используйте следующую функцию:

public DataTable dataTableColsToOtherType(DataTable dt, Type type, List<string> colsForTypeChange = default(List<string>))
        {
            var dt2 = new DataTable();
            foreach (DataColumn c in dt.Columns)
            {
                if (colsForTypeChange != null && colsForTypeChange.Count > 0)
                {
                    if (colsForTypeChange.Contains(c.ColumnName))
                        dt2.Columns.Add(c.ColumnName, type);//Change column type if found in list "colsForTypeChange"
                    else dt2.Columns.Add(c.ColumnName, c.DataType);//No change in Column Type
                }
                else
                {
                    dt2.Columns.Add(c.ColumnName, type);//change all columns type to provided type
                }
                
            }
            dt2.Load(dt.CreateDataReader(), System.Data.LoadOption.OverwriteChanges);
            return dt2;
        }

чтобы изменить тип всех столбцов назовите его как:
DataTable dtNew = dataTableColsToOtherType(dtOld, typeof(string));

чтобы изменить определенный тип столбцов назовите его как:
DataTable dtNew = dataTableColsToOtherType(dtOld, typeof(string), new List<string>() { "INT_COLUMN_1","INT_COLUMN_2" });

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


Рейтинг:
24

Varun Sareen

Дорогой Дигиману,

Вы не можете изменить тип данных datatable, как только данные будут заполнены в него.

Для получения дополнительной информации перейдите по ссылке:-

http://stackoverflow.com/questions/2538477/changing-populated-datatable-column-data-types[^]

Надеюсь, это вам поможет.

Спасибо


Рейтинг:
13

Wendelius

Во-первых, я должен признать, что не понимаю, почему вы не создаете столбцы с правильными типами данных в первую очередь. Это избавило бы нас от многих неприятностей.

Однако, отвечая на ваш вопрос, вы можете, например, загрузить данные в новую таблицу данных с помощью datatablereader. Рассмотреть следующее:

System.Data.DataTable dt = new System.Data.DataTable();
dt.Columns.Add("Col1", typeof(int));
dt.Rows.Add(1);

System.Data.DataTable dt2 = new System.Data.DataTable();
dt2.Columns.Add("Col1", typeof(string));
dt2.Load(dt.CreateDataReader(), System.Data.LoadOption.OverwriteChanges);


Herman&lt;T&gt;.Instance

вот это круто: System.Data.LoadOption.Переписать изменения. Это доставляет много хлопот.



Вы говорите: "во-первых, я должен признать, что не понимаю, почему вы не создаете столбцы с правильными типами данных в первую очередь".
Причина в том, что база данных предоставляет мне эту datatable на основе хранимой процедуры, которая используется для нескольких отчетов и может содержать от 1 до 15 строк данных. Основываясь на количестве строк, я могу определить, какая строка должна быть установлена вместо значения int.

Wendelius

Ладно, это имеет смысл :)

FarhanShariff

Я хочу, чтобы изменить тип объекта DataTable в десятичную, как я это делаю

пространство имен ReadDataFromCSVFile
{
программа статического класса
{
статический недействительным Главная()
{
строка csv_file_path = @"C:\Matlab\Sheet1_t168h.csv";
DataTable csvData = GetDataTabletFromCSVFile(csv_file_path);
Приставка.WriteLine("количество строк:" + csvData.Rows.Рассчитывать);
Приставка.Линия чтения();
}
private static DataTable GetDataTabletFromCSVFile(строка csv_file_path)
{
DataTable csvData = новый DataTable();

using (TextFieldParser csvReader = new TextFieldParser(csv_file_path))
{
csvReader.SetDelimiters(новая строка[] { "," });
csvReader.HasFieldsEnclosedInQuotes = true;
string[] colFields = csvReader.ReadFields();
foreach (строковый столбец в colFields)
{
DataColumn datecolumn = новый столбец datacolumn(столбец);
datecolumn.AllowDBNull = true;
csvData.Столбцы.Добавить(datecolumn);
}
в то время как (!csvReader.EndOfData)
{
string[] fieldData = csvReader.ReadFields();
//Создание пустого значения как null
for (int i = 0; i < fieldData.Длина; i++)
{
if (fieldData[i] == "")
{
fieldData[i] = null;
}
}
csvData.Rows.Add(fieldData);
}
}


возврат csvData;
}
}
}

#realJSOP

Эй, Майк, я понимаю, что это действительно старая книга, но у меня есть причина, по которой ты не устанавливаешь тип, подходящий для первого раунда. Я загружал/анализировал CSV-файл и просто добавлял проанализированные данные в объект datatable, а затем устанавливал столбец DataType собственность на object, а затем определил соответствующие типы из данных в datatable. Только после того, как я получил весь код на месте, я понял, что вы не можете установить тип после того, как в datatable были строки, поэтому я создал новый метод, который был вызван в конце цепочки обработки:

protected virtual void SetColumnTypes()
{
    if (this.ColumnHints != null)
    {
        DataTable cloned = this.ImportedData.Clone();
        for (int i = 0; i < cloned.Columns.Count; i++)
        {
            // ColumnHints is an object that determines the datatypes
            // for the imported CSV fields by iterating all of the
            // rows/columns of the initial datatable
            cloned.Columns[i].DataType = ColumnHints[i].ItemType;
        }
        foreach (DataRow row in this.ImportedData.Rows)
        {
            cloned.ImportRow(row);
        }
        this.ImportedData = cloned;
    }
}


Так что, как видите, иногда в этом есть необходимость.

Maciej Los

Джон, зачем использовать цикл [foreach] для копирования данных между таблицами данных? Вместо этого вы можете использовать метод [CopyToDataTable()] :

cloned = this.ImportedData.CopyToDataTable();
this.ImportedData = cloned;

#realJSOP

Детали неясны, но я, кажется, помню, что получал странные результаты, когда делал это таким образом. Поскольку моя память заполнена большим количеством дыр, чем заявления Хиллари Клинтон о ее почтовом сервере, я не могу точно вспомнить, в чем была проблема, хотя вполне вероятно, что я хотел следить за процессом импорта строк и просто не вернулся к использованию CopyToDataTable метод.

Maciej Los

ОК.
Овации,
Мацей