ডেটা টেবিলের ডেটা কলামের ডেটা টাইপ কীভাবে পরিবর্তন করবেন?


120

আমার আছে:

DataTable Table = new DataTable;
SqlConnection = new System.Data.SqlClient.SqlConnection("Data Source=" + ServerName + ";Initial Catalog=" + DatabaseName + ";Integrated Security=SSPI; Connect Timeout=120");

SqlDataAdapter adapter = new SqlDataAdapter("Select * from " + TableName, Connection);
adapter.FillSchema(Table, SchemaType.Source);
adapter.Fill(Table);

DataColumn column = DataTable.Columns[0];

আমি যা করতে চাই তা হ'ল:

বর্তমানে ধরে column.DataType.Name হয় "নকল" । আমি এটি "ইন্ট 32" হয়ে উঠতে চাই ।

আমি কীভাবে এটি অর্জন করব?

উত্তর:


269

ডেটাবেল ডেটা পূরণের পরে আপনি ডেটাটাইপ পরিবর্তন করতে পারবেন না। তবে, আপনি ডেটা টেবিলটি ক্লোন করতে পারেন, কলামের ধরণটি পরিবর্তন করতে পারেন এবং পূর্বের ডাটা টেবিল থেকে ক্লোন টেবিলটিতে ডেটা লোড করতে পারেন নীচের মত।

DataTable dtCloned = dt.Clone();
dtCloned.Columns[0].DataType = typeof(Int32);
foreach (DataRow row in dt.Rows) 
{
    dtCloned.ImportRow(row);
}

সমাধান ভালোবাসি - মার্জিত! তবে ইম্পোর্টআর () আমার কাছে স্ট্রিং মানকে ভাসমান মানগুলিতে রূপান্তর করবে বলে মনে হয় না। আমি কি এখানে কিছু মিস করছি?
yangli.liy

1
DataTable.ImportRow () (বা বরং এটির অন্তর্নিহিত স্টোরেজ) আইকনভারটিবল ইন্টারফেস ব্যবহার করে মানগুলিতে রূপান্তর করে। সম্পত্তি ডেটা টেবিল সেট করার বিষয়টি নিশ্চিত করুন according অনুসারে লোকাল! (ডিফল্ট সংস্কৃতিInfo.C موجودہ সংস্কৃতি)
স্যার কিল এ লট

এটা কাজ করে না. আমি ডিবি আসার বাইট অ্যারে কলামের পরিবর্তে একটি স্মৃতিধারার কলাম তৈরি করার চেষ্টা করছি। এটি সিস্টেমটি দেয়। প্রত্যাশিত প্রকারটি হ'ল
মেমরিস্ট্রিম

28

যদিও এটি সত্য যে আপনি DataTableপূরণ করার পরে কলামের ধরণটি পরিবর্তন করতে পারবেন না , আপনি কল করার পরে এটি কল করতে পারেন FillSchemaতবে কল করার আগে Fill। উদাহরণ হিসেবে বলা যায়, বলে 3rd কলাম এক আপনার কাছ থেকে রূপান্তর করতে চান doubleকরতে Int32, আপনি ব্যবহার করতে পারে:

adapter.FillSchema(table, SchemaType.Source);
table.Columns[2].DataType = typeof (Int32);
adapter.Fill(table);

1
মনে রাখবেন যে আপনার অ্যাডাপ্টারের কমান্ডটি কোনও সঞ্চিত প্রক্রিয়া হলে এটি কাজ করে না বলে মনে করেন
মার্ক সোওল

1
আমি এটি Oracle.MangedDataAccess.Client.OracleDataAdapterএকটি সঞ্চিত প্রক্রিয়া দিয়ে পরীক্ষা করেছি । ইহা কাজ করছে. ধন্যবাদ।
3

21

পুরানো পোস্ট, তবে আমি ভেবেছিলাম যে আমি ডেটা টেবিল এক্সটেনশন দিয়ে ওজন করব যা একটি সময়ে একটি একক কলামকে একটি নির্দিষ্ট ধরণের রূপান্তর করতে পারে:

public static class DataTableExt
{
    public static void ConvertColumnType(this DataTable dt, string columnName, Type newType)
    {
        using (DataColumn dc = new DataColumn(columnName + "_new", newType))
        {
            // Add the new column which has the new type, and move it to the ordinal of the old column
            int ordinal = dt.Columns[columnName].Ordinal;
            dt.Columns.Add(dc);
            dc.SetOrdinal(ordinal);

            // Get and convert the values of the old column, and insert them into the new
            foreach (DataRow dr in dt.Rows)
                dr[dc.ColumnName] = Convert.ChangeType(dr[columnName], newType);

            // Remove the old column
            dt.Columns.Remove(columnName);

            // Give the new column the old column's name
            dc.ColumnName = columnName;
        }
    }
}

এটি তখন এভাবে বলা যেতে পারে:

MyTable.ConvertColumnType("MyColumnName", typeof(int));

অবশ্যই আপনি যে ধরণের পছন্দ করতে চান, যতক্ষণ না কলামের প্রতিটি মান প্রকৃতপক্ষে নতুন ধরণের রূপান্তরিত হতে পারে।


ত্রুটি দেয় "অবজেক্টটি অবশ্যই আইকনভারটেবল প্রয়োগ করতে পারে।" বাইট [] কে স্ট্রিং টাইপ কলামে রূপান্তর করার সময়।
হর্ষদ ভেকেরিয়া

এটিতে কিছু জেনেরিক যুক্ত করুন public static void ConvertColumnType<T>(this DataTable dt, string columnName, TnewType) where T : Type, IConvertible
টিএম

3
আমি মনে করি এটি সবচেয়ে মার্জিত সমাধান, কেবলমাত্র DBNulls রূপান্তর করা এড়ানো, যেমন dr[dc.ColumnName] = dr[columnName] == DBNull.Value ? DBNull.Value : Convert.ChangeType(dr[columnName], newType);
মাইবোপার

8

রিটার্নের ধরণের পরিবর্তনও বিবেচনা করুন:

select cast(columnName as int) columnName from table


8

আমি কিছুটা ভিন্ন পদ্ধতি নিয়েছি। ওএ তারিখের ফর্ম্যাটে থাকা এক্সেল আমদানি থেকে আমার একটি ডেটটাইম পার্স করা দরকার। এই পদ্ধতিটি ... ... সংক্ষেপে এগুলি তৈরি করার পক্ষে যথেষ্ট সহজ,

  1. আপনার পছন্দ মতো কলাম যুক্ত করুন
  2. মান রূপান্তরকারী সারিগুলির মধ্য দিয়ে চিড়ে ফেলা
  3. মূল কলামটি মুছুন এবং পুরানোটির সাথে মেলে নতুন নামকরণ করুন

    private void ChangeColumnType(System.Data.DataTable dt, string p, Type type){
            dt.Columns.Add(p + "_new", type);
            foreach (System.Data.DataRow dr in dt.Rows)
            {   // Will need switch Case for others if Date is not the only one.
                dr[p + "_new"] =DateTime.FromOADate(double.Parse(dr[p].ToString())); // dr[p].ToString();
            }
            dt.Columns.Remove(p);
            dt.Columns[p + "_new"].ColumnName = p;
        }

ধন্যবাদ! ঠিক আমি খুঁজছেন ছিল কি.
রাহুল সিং

4

একবার DataTableপূরণ হয়ে গেলে আপনি কোনও কলামের ধরণ পরিবর্তন করতে পারবেন না।

এই দৃশ্যে আপনার সর্বোত্তম বিকল্প হ'ল একটি Int32কলাম DataTableপূরণ করার আগে এটি যুক্ত করা:

dataTable = new DataTable("Contact");
dataColumn = new DataColumn("Id");
dataColumn.DataType = typeof(Int32);
dataTable.Columns.Add(dataColumn);

তারপরে আপনি আপনার মূল টেবিল থেকে নতুন টেবিলে ডেটা ক্লোন করতে পারেন:

DataTable dataTableClone = dataTable.Clone();

আরও বিশদ সহ একটি পোস্ট এখানে ।


4

যদি আপনি কেবল একটি কলাম পরিবর্তন করতে চান example উদাহরণস্বরূপ স্ট্রিং থেকে ইন্ট 32 এ আপনি এক্সপ্রেশন সম্পত্তি ব্যবহার করতে পারেন:

DataColumn col = new DataColumn("col_int" , typeof(int));
table.Columns.Add(col);
col.Expression = "table_exist_col_string"; // digit string convert to int  

ভাল উত্তর! (...) এবং নাল মানগুলি পরীক্ষা করার দরকার নেই ।
বেহজাদ ইব্রাহিমি

2

আমি একটি এক্সটেনশন ফাংশন তৈরি করেছি যা একটি ডেটা টেবিলের কলামের ধরণের পরিবর্তন করতে দেয়। পুরো টেবিলটি ক্লোনিং করে এবং সমস্ত ডেটা আমদানির পরিবর্তে এটি কলামটি কেবলমাত্র ক্লোন করে, মানটিকে বিশ্লেষণ করে এবং আসলটি মুছে দেয়।

    /// <summary>
    /// Changes the datatype of a column. More specifically it creates a new one and transfers the data to it
    /// </summary>
    /// <param name="column">The source column</param>
    /// <param name="type">The target type</param>
    /// <param name="parser">A lambda function for converting the value</param>
    public static void ChangeType(this DataColumn column, Type type, Func<object, object> parser)
    {
        //no table? just switch the type
        if (column.Table == null)
        {
            column.DataType = type;
            return;
        }

        //clone our table
        DataTable clonedtable = column.Table.Clone();

        //get our cloned column
        DataColumn clonedcolumn = clonedtable.Columns[column.ColumnName];

        //remove from our cloned table
        clonedtable.Columns.Remove(clonedcolumn);

        //change the data type
        clonedcolumn.DataType = type;

        //change our name
        clonedcolumn.ColumnName = Guid.NewGuid().ToString();

        //add our cloned column
        column.Table.Columns.Add(clonedcolumn);

        //interpret our rows
        foreach (DataRow drRow in column.Table.Rows)
        {
            drRow[clonedcolumn] = parser(drRow[column]);
        }

        //remove our original column
        column.Table.Columns.Remove(column);

        //change our name
        clonedcolumn.ColumnName = column.ColumnName;
    }
}

আপনি এটি এর মতো ব্যবহার করতে পারেন:

List<DataColumn> lsColumns = dtData.Columns
    .Cast<DataColumn>()
    .Where(i => i.DataType == typeof(decimal))
    .ToList()

//loop through each of our decimal columns
foreach(DataColumn column in lsColumns)
{
    //change to double
    column.ChangeType(typeof(double),(value) =>
    {
        double output = 0;
        double.TryParse(value.ToString(), out output);
        return output;  
    });
}

উপরের কোডটি সমস্ত দশমিক কলামগুলি ডাবলস এ পরিবর্তন করে।


1
DataTable DT = ...
// Rename column to OLD:
DT.Columns["ID"].ColumnName = "ID_OLD";
// Add column with new type:
DT.Columns.Add( "ID", typeof(int) );
// copy data from old column to new column with new type:
foreach( DataRow DR in DT.Rows )
{ DR["ID"] = Convert.ToInt32( DR["ID_OLD"] ); }
// remove "OLD" column
DT.Columns.Remove( "ID_OLD" );

1

আমি মার্ক এর সমাধান দক্ষতা মিলিত - তাই আমি করতে হবে না .Cloneসমগ্র DataTable , জেনেরিক্স এবং extensibility সাথে তাই - আমি আমার নিজের রূপান্তর ফাংশন নির্ধারণ করতে পারবেন । এটিই আমি শেষ করেছি:

/// <summary>
///     Converts a column in a DataTable to another type using a user-defined converter function.
/// </summary>
/// <param name="dt">The source table.</param>
/// <param name="columnName">The name of the column to convert.</param>
/// <param name="valueConverter">Converter function that converts existing values to the new type.</param>
/// <typeparam name="TTargetType">The target column type.</typeparam>
public static void ConvertColumnTypeTo<TTargetType>(this DataTable dt, string columnName, Func<object, TTargetType> valueConverter)
{
    var newType = typeof(TTargetType);

    DataColumn dc = new DataColumn(columnName + "_new", newType);

    // Add the new column which has the new type, and move it to the ordinal of the old column
    int ordinal = dt.Columns[columnName].Ordinal;
    dt.Columns.Add(dc);
    dc.SetOrdinal(ordinal);

    // Get and convert the values of the old column, and insert them into the new
    foreach (DataRow dr in dt.Rows)
    {
        dr[dc.ColumnName] = valueConverter(dr[columnName]);
    }

    // Remove the old column
    dt.Columns.Remove(columnName);

    // Give the new column the old column's name
    dc.ColumnName = columnName;
}

এইভাবে, ব্যবহার অনেক বেশি সহজবোধ্য, পাশাপাশি কাস্টমাইজযোগ্য:

DataTable someDt = CreateSomeDataTable();
// Assume ColumnName is an int column which we want to convert to a string one.
someDt.ConvertColumnTypeTo<string>('ColumnName', raw => raw.ToString());

0

পুয়েডেস এগ্রিগার aনা কলম্বনা কন টিপো ডি ডেটো স্পষ্টত, লুয়েগো কপিয়ার লস ডেটোস ওয়াই এলিমিনিয়ার লা কলুমনা পূর্ববর্তী

TB.Columns.Add("columna1", GetType(Integer))    
TB.Select("id=id").ToList().ForEach(Sub(row) row("columna1") = row("columna2"))    
TB.Columns.Remove("columna2")

1
আপনার উত্তরে আপনার কিছু প্রসঙ্গ যুক্ত করা উচিত, কোডের উত্তরের কোনও মূল্য নেই কারণ এগুলি নিম্ন মানের হিসাবে দেখা হয়।
নাভেদ নবী জাদা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.