zoukankan      html  css  js  c++  java
  • 【唠叨两句】如何将一张树型结构的Excel表格中的数据导入到多张数据库表中

             小弟昨天遇到一个相对比较棘手的问题,就像标题说的那样、如何将一张树型结构的Excel表格中的数据导入到多张数据库表中,在现实中实际是七张数据库表,这七张表之间有着有着相对比较复杂的主外键关系,对于我这么洼的水平,刚遇到时确实愣了一下。不过还好、等冷静下来之后,慢慢的找到的了解决的办法。现在与大家分享一下处理思路及方法。

    先说一下这里用到的一些主要的东东吧:
    一、DataView类:
    构造函数 DataView(dataTable)

    方法
     dataView.ToTable(String, Boolean, String[]) 【已重载】
    方法解释:根据现有 DataView 中的行,创建并返回一个新的 DataTable。

    二、DataTable类
    dataTable.Merge(dataTable);[已重载]
    方法解释:将指定的 DataTable 与当前的 DataTable 合并


    三、DataRelation类:该类是用来表示两个DataTable中间的关系的。
    DataRelation 的一项主要功能就是在 DataSet 中从一个 DataTable 浏览到另一个。 它使您能够在给定相关 DataTable 中的单个 DataRow 的情况下检索一个 DataTable 中的所有相关 DataRow 对象。

    DataRelation 常用的构造函数,还有其他构造函数哦

    名称

    说明

    DataRelation(String, DataColumn, DataColumn)

    使用指定的 DataRelation 名称,父级和子级 DataColumn 对象,初始化 DataRelation 类的新实例。

    DataRelation(String, DataColumn[], DataColumn[])

    使用指定的 DataRelation 名称以及父级和子级 DataColumn 对象的匹配的数组,初始化 DataRelation 类的新实例。

    DataRelation中的常用属性

    ChildColumns

    获取此关系的子 DataColumn 对象。

    ChildTable

    获取此关系的子表。

    DataSet

    获取 DataRelation 所属的 DataSet。

    ParentColumns

    获取作为此 DataRelation 的父列的 DataColumn 对象的数组。

    ParentTable

    获取此 DataRelation 的父级 DataTable。

    RelationName

    获取或设置用于从 DataRelationCollection 中检索 DataRelation 的名称。


    关于DataRelation的一个MSDN上的简单例子:
     

    DataRelation customerOrdersRelation =
        customerOrders.Relations.Add("CustOrders",
        customerOrders.Tables["Customers"].Columns["CustomerID"],
        customerOrders.Tables["Orders"].Columns["CustomerID"]);

    foreach (DataRow custRow in customerOrders.Tables["Customers"].Rows)
    {
        Console.WriteLine(custRow["CustomerID"].ToString());

        foreach (DataRow orderRow in custRow.GetChildRows(customerOrdersRelation))
        {
            Console.WriteLine(orderRow["OrderID"].ToString());
        }
    }

    四、SqlBulkCopy 对象【适用于MSSQL】:用于极速插入数据

    有了上述的这些东西我们就可以实现将一张树型结构的Excel表格中的数据导入到多张数据库表中了,下面我简单的说一下我的思路 及 处理方法。

    在此以 类 、项、 种 为例,其中类是项的上一级,项是种的上一级。

    类       数据库 表名:Classcification 字段名:ClassificationID【PK】,ClassificationName
    项      数据库 表名:Term            字段名:TermID【PK】, TermName, ClassificationID
    种      数据库 表名:Kind            字段名:KindID【PK】, KindName, TermID


    先定义两个全局私有字段
     

            #region 全局私有字段

            /// <summary>

            /// 源数据视图

            /// </summary>

            private DataView dvSource;

            /// <summary>

            /// 全部变量用来临时存放三个表及三个表之间的关系DataRelation

            /// </summary>

            private DataSet dsTemp;

            #endregion

    //全局阶段(1)

    建立DataTable及关系并保存
    #region 类、项、种 注意此时的数据表与数据库的表结构不一致

    //

    DataTable Classification
    =new DataTable("Classification");

    Classification.Columns.Add(
    "ClassificationID");

    Classification.Columns.Add(
    "ClassificationName");

    this.dsTemp.Tables.Add(Classification);



    //

    DataTable Term
    =new DataTable("Term");

    Term.Columns.Add(
    "TermID");

    Term.Columns.Add(
    "TermName");

    Term.Columns.Add(
    "ClassificationID");



    //辅助作用

    Term.Columns.Add(
    "ClassificationName");



    //保存DataTable至全局变量DataSet中

    this.dsTemp.Tables.Add(Term);



    //建立类与项之间的关系

    DataRelation ReClassTerm
    =new DataRelation("ReClassTerm", Classification.Columns["ClassificationName"], Term.Columns["ClassificationName"]);



    //保存关系至DataSet

    this.dsTemp.Relations.Add(ReClassTerm);



    //

    DataTable Kind
    =new DataTable("Kind");

    Kind.Columns.Add(
    "KindID");

    Kind.Columns.Add(
    "KindName");

    Kind.Columns.Add(
    "TermID");



    //辅助作用

    Kind.Columns.Add(
    "TermName");



    //保存DataTable至全局变量DataSet中

    this.dsTemp.Tables.Add(Kind);



    //建立关系

    DataRelation ReTermKind
    =new DataRelation("ReTermKind", Term.Columns["TermName"], Kind.Columns["TermName"]);



    //保存关系至Dataset

    this.dsTemp.Relations.Add(ReTermKind);

    #endregion


    处理方式见下:

     、、前台工作
    将Excel保存到DataTable中,然后将DataTable 传至后台

    、、后台工作

            // 数据处理:利用前台传过来的DataTable实例化全局的DataView

            // 全局阶段

            // (1)生成 七张数据表DataTable 及他们之间的关系保存到全局DataSet中

            // (2)源数据视图.ToTable()生成一个新的Table实例【此时的表中含有辅助作用的数据列】【Merge到 全局DateSet的相应表中】

            //

            // 类-阶段

            // (1)【获取全局DateSet中相应的表中的数据】 保存到DataTable

            // (2)获取数据库中已有的数据行

            // (3)Foreach循环对比过滤重复数据行、将数据库中已经存在的数据行从当前的DataTable中移除。

            // (4)写入主键值DateTime.Now.Ticks.ToString(); 用自动加一的方式赋值主键

            // (5)用数据库框架结构表Merge(当前的数据表)

            // (6)SqlBulkCopy。WriteToServer(数据库框架结构表)【向数据库中插入数据】

            // (7)清空当前DateSet中的当前表的所有记录

            // (8)从数据库中读取所有的新记录,然后再次保存到全局DataSet中的相应表中

            // 项-阶段

            // (9) 【获取全局DateSet中相应的表中的数据】 保存到DataTable

            // (10)获取数据库中已有的数据行

            // (11)Foreach循环对比过滤重复数据行即将数据库中已经存在的数据行从当前的DataTable中移除。

            // (12)将父表的主键值写入到当前表的相应的数据列中【此时需要借助DataRelation连接父表】

            // (13)注意:移除辅助作用数据列【因为数据库中不存在该数据列】

            // (14)用数据库框架结构表Merge(当前的数据表)

            // (15)SqlBulkCopy。WriteToServer(数据库框架结构表)【插入数据】

            // (16)清空当前DateSet中的当前表的所有记录

            // (17)从数据库中读取所有的新记录,然后再次保存到全局DataSet中的相应表中

            // 种-阶段 类似于项阶段


    OK,到此结束了。。。

    最后再唠叨两句,对于三个表而言这样做是有点繁琐了,但是对于多表而言,这样做我感觉还是不错的。

    在整个过程中有两点需要注意:

    (1)Merge的使用,这个方法使用来合并相识的两个DataTable,此方法不但能够改变Table中的数据而且可以改变table的结构。

    (2)关于DateSet的,千万不能 用新DataTable 去赋值 全局DataSet中的DataTable,否则其DataRelation将会失效。此时如果想对DataSet中的某一个DataTable 用DataTable去赋值,请选用Merge方法。

    如果大侠们还有好的建议或者想法 欢迎指教。。。

    嘿嘿,我要休息喽。。。



     



    返回导读目录,阅读更多随笔



    分割线,以下为博客签名:

    软件臭虫情未了
    • 编码一分钟
    • 测试十年功


    随笔如有错误或不恰当之处、为希望不误导他人,望大侠们给予批评指正。

  • 相关阅读:
    母函数详解
    java中为什么要实现序列化,什么时候实现序列化?
    cocos2dx&cocosbuilder折腾记
    Unity3D系列教程–使用免费工具在Unity3D中开发2D游戏 第二节(下)
    分頁查詢
    獲取CPU,硬盤序列號
    spcomm
    dbgrideh的導入和導出
    程序窗体及控件自适应分辨率
    組合的藝術
  • 原文地址:https://www.cnblogs.com/08shiyan/p/1800362.html
Copyright © 2011-2022 走看看