class_STL
2015-07-31 08:19
采纳率: 33.3%
浏览 5.3k

C# DataTable格式转换的问题。

本人在做一个数据库 入库工具。可以把文本文件(.txt文件)中的数据,筛选(要区分分隔符和数据)。导入到指定的数据库表中。
思路是这样的:
1.在内存中创建一个表ResourceTable,并创建数据行,同时规定了这个表的每个列的数据类型(这个很重要)。
2.然后,逐行读取.txt文件。筛选。把数据和分隔符区分开来。并把要存入对应列的数据,转换成该列的数据类型(也就是说转换成ResourceTable中列的数据类型)。
3.把这个表导入到数据库。
但是小弟在第2步。碰到了问题。
问题是:
怎么根据ResourceTable列的数据类型,把要存入该列的数据进行类型转换。这个要怎么做?
描述一下问题吧。贴些代码。免得像我在QQ群里面一下,问了半天,没人懂。我问了什么?
图片说明
这个是小弟的程序界面,大家可以大致的了解是个什么东西。

这个是读.txt文件的代码段,
///
/// 读取文本文件,获取指定行数
///
/// 用于保存数据的table
/// 文本文件的路径
/// 分隔字符串
/// 要读取的行数
/// 如果获取到指定的行数,则正常,否则返回false代表失败。
public static bool ReaderText(DataTable saveTable,string TextFilePath,string SplitString,UInt64 RowsCount )
{

        /*分隔措施*/
        string[] data_mark = new string[] { "data" };
        String[] sep_string = SplitString.Split(data_mark, StringSplitOptions.RemoveEmptyEntries);   //通过切割字符串,把所有的非data标志的数据,判定为分隔符
        string[] one_line;        //文本文件中的一行
        string badrow=null;      //坏行,存在问题的行
        /*构建文件流读取器*/
        StreamReader sr;
        FileStream fs ;
        try
        {
            fs= File.OpenRead(TextFilePath);    //创建文件流对象
            sr = new StreamReader(fs, Encoding.Default);     //创建一个指向文件的流读取器

        }
        catch (Exception)
        {
            return false;       //出现异常,读取失败
            throw;
        }

        /*读取指定的行数并存入表中*/
        for (UInt64 i = 0; i < RowsCount; i++)
        {
            try
            {
                DataRow one_row = saveTable.NewRow();
                badrow=sr.ReadLine();
                one_line = badrow.Split(sep_string, StringSplitOptions.RemoveEmptyEntries);      //把取出来的分隔符数组作为切割标志,对从文本文件读到的数据进行分隔
                for (int j = 0; j < one_line.Length; j++)        //创建行,并往行里面添加数据
                {
                    one_row[j] = one_line[j];
                //    MessageBox.Show(saveTable.Columns[j].DataType.FullName);
                   one_row[j]=(saveTable.Columns[j].DataType.FullName)one_line[j].ToString();       //【这里需要把存入saveTable的数据进行类型转换,
                                                                                                    //转换成和saveTable的对应列的数据类型一致。
                                                                                                    //因为我的saveTable是把对应的列设置了数据类型的。
                //    (typeof(saveTable.Columns[j].DataType.FullName));
                //    System.Convert.(saveTable.Columns[j].DataType.FullName).
                }
                saveTable.Rows.Add(one_row);     //把这一行添加到表里面
                Form1.getInstance().progressBar1.PerformStep();
            }
            catch (Exception)
            {
                BadRowsProcess(badrow, TextFilePath);       //对坏行进行处理

               // throw;
            }

        }
        sr.Dispose();
        fs.Dispose();
        return true;    //正常读完了
    }

这里是构建那个ResourceTable的代码段。
private void button_Insert_Click(object sender, EventArgs e) //开始入库按钮
{
ResourceTable = new DataTable();
ResourceTable.Clear();
/*构建一下源表*/
DataTable TargetTableDes = ADO.selectOracle("select column_name,data_type,DATA_LENGTH from user_tab_columns where table_name='" + comboBox1.SelectedItem.ToString() + "'");
foreach (DataRow item in TargetTableDes.Rows)
{
ResourceTable.Columns.Add("【" + item[0].ToString() + "】" + item[1].ToString() + "(" + item[2].ToString() + ")"); //增加列名
ResourceTable.Columns["【" + item[0].ToString() + "】" + item[1].ToString() + "(" + item[2].ToString() + ")"].DataType = Type.GetType(item[1].ToString()); //给列限制数据类型。
}

小弟想问,怎么根据ResourceTable的列的数据类型,把存入这个列的数据,转换成和这个列的数据类型一致的。

而且这个问题还有以下几个特点:
1.ResourceTable的列不止一个,而且不同的列,数据类型可能不同。同时,用户,可能把同样的数据,导入不同的表,所以ResourceTable列的列数和列的数据类型。都是根据用户的选择,在程序运行期间确定的。
2.数据库的类型和C#的类型,不完全相同。比如数据库的date类型,等等。可能会碰到在数据库的类型中有,而在C#的类型中没有的情况。那这种情况要怎么处理?
3.这个数据类型转换语句,是要求性能的。因为可能要读上百万行的文本文件,而且对每一个列都要进行转换。最好是一行代码就可以完成这个功能。

好的啰嗦了点。求各位大神,指点指点,希望大家能看懂我的需求。也就是一个数据类型转换的问题。

第一次提问啊。表达不清楚之处。多多谅解,要是还是看不懂,就问我。我再补充。

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

7条回答 默认 最新

  • x4177c 2015-07-31 08:34
    已采纳

    读大文件最好是用流,一行一行的读,读完一行后马上做分析,把分析的结果放在一个内存表中,当内存表的行数据达到一定数量时,就要把这些记录同步到DB中,这样保存内存占用合理不会内存溢出。

    已采纳该答案
    打赏 评论
  • 你这种要求反射不知道能否能过,但是你说上百万行,反射效率比较低。

    直接一个swith语句好搞点
    swith(saveTable.Columns[j].DataType.FullName){
    case xxxx:...break;
    case xxxxx:...break;
    }

    打赏 评论
  • ydz0557 2015-07-31 09:02

    我也不知道答案是什么

    打赏 评论
  • 南天空 2015-07-31 09:04

    简单说下看法,数据库里的表的列的数据类型应该是已经确定的吧?比如第一列是string ,第二列是int ,第三个列是datetime ,你直接根据表建一个类,将列的数据变成类的相应类型字段,读取txt后
    用一个泛型保存读取的数据,然后再往数据库里存,这样类的字段本身就是数据库的字段的类型,就不用再转了,转换过程在对泛型赋值的过程中。流读取的的数据类型如果不转化的话都是字符串类型,,你在赋值的时候直接转就行

    打赏 评论
  • 策龙先生 2015-07-31 10:01

    one_row[j] = one_line[j];
    他要做的是把one_line[j]的值的类型转换成one_row[j]列的值的类型
    one_row[j] = (typeof(saveTable.Columns[j].DataType.FullName))one_line[j];
    这样不行吗

    打赏 评论
  • 策龙先生 2015-07-31 10:02

    one_row[j] = one_line[j];
    他要做的是把one_line[j]的值的类型转换成one_row[j]列的值的类型
    one_row[j] = (typeof(saveTable.Columns[j].DataType.FullName))one_line[j];
    这样不行吗

    打赏 评论
  • 纳德拉 2015-07-31 14:04

    可尝试考虑使用下linq。它的一些高级语法使用起来非常方便。对于数据类型的转换使用C#的函数就可以了。

    打赏 评论

相关推荐 更多相似问题