批量向数据库多张表导入数据的实现

转载自  http://blog.csdn.net/mazhaojuan/article/details/8598368

前面已经介绍过如何向数据库的一张表中批量导入数据,详情见博客《项目经验---简单三层使用DataTable向数据库表批量导入数据---向SqlServer一张表中导入数据》;本文主要介绍如何向SqlServer的多张表中批量导入数据。

    如今有这样一个需求,需要批量导入建筑信息,依据数据库表结构设计,批量导入建筑信息,需要向数据库相应的三张表都写入数据。

看一下数据库表结构设计:

   在建筑表(TB_Building)中,BuildingID是主键,在建筑类型表(TB_BuildingType)中BuildingTypeID是主键,建筑表与建筑类型之间的关系通过第三张表(建筑类型关系表《TBR_BuildingTypeLink》)来维护,建筑与建筑类型关系表保证了数据的唯一性!   导入建筑信息,需要同时导入建筑与建筑类型的关系,还需要导入建筑与校区的关系(哪一个校区的建筑)。

   

  

下面借助《批量导入建筑信息》的实例讲解批量向数据库多张表导入数据的方法。

1.界面设计

  观看一下批量导入建筑信息的界面设计:

    

2.框架结构

   此项目的实现,我依然采用简单的三层,看一下项目框架

     

3.批量向数据库多张表导入数据的实现

  下面逐层介绍向数据库导入数据各层的代码实现:

  3.1 SqlHelper数据库助手类中添加向数据库表导入数据的方法(SqlHelper.cs)

  1. <span style="font-family: KaiTi_GB2312; font-size: 18px;">#region 批量导入DataTable  
  2.        /// <summary>批量导入DataTable  
  3.        /// 批量导入DataTable  
  4.        /// </summary>  
  5.        /// <param name="dt">DataTable数据表</param>  
  6.        /// <param name="tableName">表名</param>  
  7.        /// <param name="dtColum">数据列集合</param>  
  8.        /// <return>Boolean值:true成功,false失败</return>  
  9.        public Boolean InsertTable(DataTable dt, string tableName, DataColumnCollection dtColum)  
  10.        {  
  11.            //打开数据库  
  12.            GetConn();  
  13.   
  14.            try  
  15.            {  
  16.   
  17.                //声明SqlBulkCopy ,using释放非托管资源  
  18.                using (SqlBulkCopy sqlBC = new SqlBulkCopy(sqlConn))  
  19.                {  
  20.   
  21.   
  22.                    //一次批量的插入的数据量  
  23.                    sqlBC.BatchSize = 1000;  
  24.                    //超时之前操作完成所允许的秒数,如果超时则事务不会提交 ,数据将回滚,所有已复制的行都会从目标表中移除  
  25.                    sqlBC.BulkCopyTimeout = 60;  
  26.   
  27.                    //設定 NotifyAfter 属性,以便在每插入10000 条数据时,呼叫相应事件。   
  28.                    //sqlBC.NotifyAfter = 10000;  
  29.                    // sqlBC.SqlRowsCopied += new SqlRowsCopiedEventHandler(OnSqlRowsCopied);  
  30.   
  31.                    //设置要批量写入的表  
  32.                    sqlBC.DestinationTableName = tableName;  
  33.   
  34.                    //自定义的datatable和数据库的字段进行对应  
  35.                    //sqlBC.ColumnMappings.Add("id", "tel");  
  36.                    //sqlBC.ColumnMappings.Add("name", "neirong");  
  37.                    for (int i = 0; i < dtColum.Count; i++)  
  38.                    {  
  39.                        sqlBC.ColumnMappings.Add(dtColum[i].ColumnName.ToString(), dtColum[i].ColumnName.ToString());  
  40.                    }  
  41.                    //批量写入  
  42.                    sqlBC.WriteToServer(dt);  
  43.                }  
  44.                //  conn.Dispose();  
  45.                //GetConn();  
  46.                return true;  
  47.            }  
  48.            catch  
  49.            {  
  50.                return false;  
  51.   
  52.            }  
  53.            finally  
  54.            {  
  55.                //关闭数据库  
  56.                sqlConn.Close();  
  57.            }  
  58.        }  
  59.        #endregion</span>  
 #region 批量导入DataTable
        /// <summary>批量导入DataTable
        /// 批量导入DataTable
        /// </summary>
        /// <param name="dt">DataTable数据表</param>
        /// <param name="tableName">表名</param>
        /// <param name="dtColum">数据列集合</param>
        /// <return>Boolean值:true成功,false失败</return>
        public Boolean InsertTable(DataTable dt, string tableName, DataColumnCollection dtColum)
        {
            //打开数据库
            GetConn();

            try
            {

                //声明SqlBulkCopy ,using释放非托管资源
                using (SqlBulkCopy sqlBC = new SqlBulkCopy(sqlConn))
                {


                    //一次批量的插入的数据量
                    sqlBC.BatchSize = 1000;
                    //超时之前操作完成所允许的秒数,如果超时则事务不会提交 ,数据将回滚,所有已复制的行都会从目标表中移除
                    sqlBC.BulkCopyTimeout = 60;

                    //設定 NotifyAfter 属性,以便在每插入10000 条数据时,呼叫相应事件。 
                    //sqlBC.NotifyAfter = 10000;
                    // sqlBC.SqlRowsCopied += new SqlRowsCopiedEventHandler(OnSqlRowsCopied);

                    //设置要批量写入的表
                    sqlBC.DestinationTableName = tableName;

                    //自定义的datatable和数据库的字段进行对应
                    //sqlBC.ColumnMappings.Add("id", "tel");
                    //sqlBC.ColumnMappings.Add("name", "neirong");
                    for (int i = 0; i < dtColum.Count; i++)
                    {
                        sqlBC.ColumnMappings.Add(dtColum[i].ColumnName.ToString(), dtColum[i].ColumnName.ToString());
                    }
                    //批量写入
                    sqlBC.WriteToServer(dt);
                }
                //  conn.Dispose();
                //GetConn();
                return true;
            }
            catch
            {
                return false;

            }
            finally
            {
                //关闭数据库
                sqlConn.Close();
            }
        }
        #endregion

 3.2 DAL层批量导入数据的代码(BuildingDAL.cs)

  

  1. #region 批量添加建筑信息  
  2.        /// <summary>  
  3.        /// 建筑管理:批量添加建筑信息:  
  4.        /// 1.向建筑表添加建筑基本信息   
  5.        /// 2.向建筑与建筑类型关联表添加建筑与建筑类型的关联信息   
  6.        /// 3.向建筑与校区关联表添加建筑与校区的关联信息  
  7.        /// </summary>  
  8.        /// <summary>  
  9.        /// 批量导入建筑信息  
  10.        /// </summary>  
  11.        /// <param name="ds">DataSet-ds;</param>  
  12.        public Boolean ImportBuilding(DataSet ds)  
  13.        {  
  14.            //定义布尔型标记变量,记录建筑是否添加成功  
  15.            //添加建筑信息  
  16.            Boolean flagAddBuilding;  
  17.            //添加建筑与建筑类型的关系  
  18.            Boolean flagAddBuildingType;  
  19.            //添加建筑与校区的关系  
  20.            Boolean flagAddBuildingCampus;  
  21.   
  22.            //执行隐式事务:报错--此操作对该状态的事务无效 的错误于是去掉了事务  
  23.            //using (TransactionScope scope = new TransactionScope())  
  24.            //{  
  25.                //调用sqlHelper的"批量导入datatable表"的方法  
  26.                flagAddBuilding = sqlHelper.InsertTable(ds.Tables["dt_AddBuilding"], "TB_Building", ds.Tables["dt_AddBuilding"].Columns);  
  27.                //调用sqlHelper的"批量导入datatable表"的方法  
  28.                flagAddBuildingType = sqlHelper.InsertTable(ds.Tables["dt_AddBuildingType"], "TBR_BuildingTypeLink", ds.Tables["dt_AddBuildingType"].Columns);  
  29.                //调用sqlHelper的"批量导入datatable表"的方法  
  30.                flagAddBuildingCampus = sqlHelper.InsertTable(ds.Tables["dt_AddBuildingCampus"], "TBR_BuildingCampusLink", ds.Tables["dt_AddBuildingCampus"].Columns);  
  31.            //}  
  32.   
  33.            //返回结果  
  34.            return (flagAddBuilding && flagAddBuildingType && flagAddBuildingCampus);  
  35.        }  
  36.  
  37.  
  38.        #endregion  
 #region 批量添加建筑信息
        /// <summary>
        /// 建筑管理:批量添加建筑信息:
        /// 1.向建筑表添加建筑基本信息 
        /// 2.向建筑与建筑类型关联表添加建筑与建筑类型的关联信息 
        /// 3.向建筑与校区关联表添加建筑与校区的关联信息
        /// </summary>
        /// <summary>
        /// 批量导入建筑信息
        /// </summary>
        /// <param name="ds">DataSet-ds;</param>
        public Boolean ImportBuilding(DataSet ds)
        {
            //定义布尔型标记变量,记录建筑是否添加成功
            //添加建筑信息
            Boolean flagAddBuilding;
            //添加建筑与建筑类型的关系
            Boolean flagAddBuildingType;
            //添加建筑与校区的关系
            Boolean flagAddBuildingCampus;

            //执行隐式事务:报错--此操作对该状态的事务无效 的错误于是去掉了事务
            //using (TransactionScope scope = new TransactionScope())
            //{
                //调用sqlHelper的"批量导入datatable表"的方法
                flagAddBuilding = sqlHelper.InsertTable(ds.Tables["dt_AddBuilding"], "TB_Building", ds.Tables["dt_AddBuilding"].Columns);
                //调用sqlHelper的"批量导入datatable表"的方法
                flagAddBuildingType = sqlHelper.InsertTable(ds.Tables["dt_AddBuildingType"], "TBR_BuildingTypeLink", ds.Tables["dt_AddBuildingType"].Columns);
                //调用sqlHelper的"批量导入datatable表"的方法
                flagAddBuildingCampus = sqlHelper.InsertTable(ds.Tables["dt_AddBuildingCampus"], "TBR_BuildingCampusLink", ds.Tables["dt_AddBuildingCampus"].Columns);
            //}

            //返回结果
            return (flagAddBuilding && flagAddBuildingType && flagAddBuildingCampus);
        }


        #endregion

 3.3 BLL层批量导入数据的代码(BuildingBLL.cs)

  1. #region 批量导入建筑信息  
  2.         /// <summary>  
  3.         /// 批量导入建筑信息  
  4.         /// </summary>  
  5.         /// <param name="ds">DataSet</param>  
  6.         /// <returns>是否导入成功:true成功,false失败</returns>  
  7.         public Boolean ImportBuiding(DataSet ds)  
  8.         {  
  9.             return buildingDAL.ImportBuilding(ds);  
  10.         }  
  11.         #endregion  
#region 批量导入建筑信息
        /// <summary>
        /// 批量导入建筑信息
        /// </summary>
        /// <param name="ds">DataSet</param>
        /// <returns>是否导入成功:true成功,false失败</returns>
        public Boolean ImportBuiding(DataSet ds)
        {
            return buildingDAL.ImportBuilding(ds);
        }
        #endregion

  3.4 界面层构造DataSet数据,向BLL层传递

   这里我依然采用从界面上传Excel,然后从Excel获取输入然后存入DataSet的各DataTable表中。

   3.4.1 界面层HTML代码(AddBuilding.aspx)

   

  1. <div class="block">  
  2.         <div class="h">  
  3.             <span class="icon-sprite icon-list"></span>  
  4.             <h3>批量导入建筑</h3>  
  5.             <div class="bar">  
  6.                 <class="btn-lit" href="javascript:history.go('<% =returnCount %>')"><span>返回</span></a>  
  7.             </div>  
  8.         </div>  
  9.         <div class="tl corner"></div>  
  10.         <div class="tr corner"></div>  
  11.         <div class="bl corner"></div>  
  12.         <div class="br corner"></div>  
  13.         <div class="cnt-wp">  
  14.             <div class="cnt form">  
  15.                 <%--<form method="post" enctype="multipart/form-data" action="">--%>  
  16.                 <table class="data-form" cellspacing="0" cellpadding="0">  
  17.                     <tr><td>  
  18.                     <asp:Label ID="Label1" runat="server" Text="提示:请导入扩展名为.xls的文件【工作薄名:Sheet1;表头(如下):】"></asp:Label>  
  19.                    </td>  
  20.                     </tr>  
  21.                     <tr><td>  
  22.                     <img src="../uploadFileImage/importBuilding.jpg"  alt=""/></td>  
  23.                     </tr>   
  24.   
  25.                     <tr>  
  26.                         <asp:FileUpload ID="fupImportBuilding" runat="server" />  
  27.                         <asp:Button ID="btnImportBuilding" runat="server" Text="批量导入" OnClick="btnImportBuilding_Click" />                     
  28.                      </tr>  
  29.                       
  30.                 </table>  
  31.                <%-- </form>--%>  
  32.             </div>  
  33.         </div>  
  34.     </div>  
  35.    
<div class="block">
        <div class="h">
            <span class="icon-sprite icon-list"></span>
            <h3>批量导入建筑</h3>
            <div class="bar">
                <a class="btn-lit" href="javascript:history.go('<% =returnCount %>')"><span>返回</span></a>
            </div>
        </div>
        <div class="tl corner"></div>
        <div class="tr corner"></div>
        <div class="bl corner"></div>
        <div class="br corner"></div>
        <div class="cnt-wp">
            <div class="cnt form">
                <%--<form method="post" enctype="multipart/form-data" action="">--%>
                <table class="data-form" cellspacing="0" cellpadding="0">
                    <tr><td>
                    <asp:Label ID="Label1" runat="server" Text="提示:请导入扩展名为.xls的文件【工作薄名:Sheet1;表头(如下):】"></asp:Label>
                   </td>
                    </tr>
                    <tr><td>
                    <img src="../uploadFileImage/importBuilding.jpg"  alt=""/></td>
                    </tr> 

                    <tr>
                        <asp:FileUpload ID="fupImportBuilding" runat="server" />
                        <asp:Button ID="btnImportBuilding" runat="server" Text="批量导入" OnClick="btnImportBuilding_Click" />                   
                     </tr>
                    
                </table>
               <%-- </form>--%>
            </div>
        </div>
    </div>
 

   3.4.2 从界面传入Excel,调用BLL层Excel转换成DataTable的方法(AddBuilding.aspx.cs)

  1. #region 批量导入建筑信息  
  2.    protected void btnImportBuilding_Click(object sender,EventArgs e) {  
  3.        //建筑业务逻辑层  
  4.        BuildingBLL buildingBLL = new BuildingBLL();  
  5.        //BLL层把Excel转化为datatable类  
  6.        CreateExcelDataBLL createExcelData = new CreateExcelDataBLL();  
  7.     
  8.        //获取上传文件地址  
  9.        string url = fupImportBuilding.PostedFile.FileName.ToString();  
  10.   
  11.        if (url == "")  
  12.        {  
  13.            //数据源为空,弹出提示:请选择Excel文件!  
  14.            Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('请选择Excel文件!');</script>");  
  15.            return;  
  16.        }  
  17.   
  18.        string urlLocation = url.Substring(url.LastIndexOf("\") + 1);//获取文件名  
  19.   
  20.        DataTable dtAllBuildingCampusType;  
  21.        //在系统中建文件夹up,并将excel文件另存  
  22.        this.fupImportBuilding.SaveAs(Server.MapPath("~\UploadFile") + "\" + urlLocation);//记录文件名到服务器相对应的文件夹中  
  23.   
  24.        //获得文件路径  
  25.        string strpath = Server.MapPath("~\UploadFile") + "\" + urlLocation;  
  26.         
  27.        //把上传的Excel转换为datatable  
  28.        dtAllBuildingCampusType = createExcelData.CreateExcelDataSource(strpath);  
  29.   
  30.        DataSet dsBuildingCampusType = new DataSet("ds_BuilingCampusType"); //创建一个名为ds_BuilingCampusType的DataSet  
  31.   
  32.        //手动创建的新数据表-建筑数据表  
  33.        DataTable dtAddBuilding = new DataTable("dt_AddBuilding"); //创建一个名为dt_AddBuilding的DataTalbe  
  34.        //为dt_AddBuilding表内建立Column(表头),添加数据列:建筑ID、建筑代码、建筑名、是否可用、备注、操作类型、操作内容、操作原因、操作人、操作时间  
  35.        dtAddBuilding.Columns.Add(new DataColumn("BuildingID", typeof(string)));  
  36.        dtAddBuilding.Columns.Add(new DataColumn("BuildingCode", typeof(string)));  
  37.        dtAddBuilding.Columns.Add(new DataColumn("BuildingName", typeof(string)));  
  38.        dtAddBuilding.Columns.Add(new DataColumn("IsAvailable", typeof(string)));  
  39.        dtAddBuilding.Columns.Add(new DataColumn("Descriptions",typeof(string)));  
  40.        dtAddBuilding.Columns.Add(new DataColumn("ActionType", typeof(string)));  
  41.        dtAddBuilding.Columns.Add(new DataColumn("ActionContent", typeof(string)));  
  42.        dtAddBuilding.Columns.Add(new DataColumn("ActionReason", typeof(string)));  
  43.        dtAddBuilding.Columns.Add(new DataColumn("Operator", typeof(string)));  
  44.        dtAddBuilding.Columns.Add(new DataColumn("SetDatetime", typeof(DateTime)));  
  45.   
  46.        //手动创建的新数据表-建筑、建筑类型关系数据表  
  47.        DataTable dtAddBuildingType = new DataTable("dt_AddBuildingType"); //创建一个名为dt_AddBuildingType的DataTalbe  
  48.        //为dt_AddBuildingType表内建立Column(表头),添加数据列:建筑ID、建筑类型ID、是否可用  
  49.        dtAddBuildingType.Columns.Add(new DataColumn("BuildingID", typeof(string)));  
  50.        dtAddBuildingType.Columns.Add(new DataColumn("BuildingTypeID", typeof(string)));  
  51.        dtAddBuildingType.Columns.Add(new DataColumn("IsAvailable", typeof(string)));  
  52.   
  53.        //手动创建的新数据表-建筑、校区关系数据表  
  54.        DataTable dtAddBuildingCampus = new DataTable("dt_AddBuildingCampus"); //创建一个名为dt_AddBuildingCampus的DataTalbe  
  55.        //为dt_AddBuildingCampus表内建立Column(表头),添加数据列:建筑ID、校区ID、是否可用  
  56.        dtAddBuildingCampus.Columns.Add(new DataColumn("BuildingID", typeof(string)));  
  57.        dtAddBuildingCampus.Columns.Add(new DataColumn("CampusID", typeof(string)));  
  58.        dtAddBuildingCampus.Columns.Add(new DataColumn("IsAvailable", typeof(string)));  
  59.   
  60.        //从上传的Excel转换为的datatable表中取出数据,分别放入建筑信息表、建筑与建筑类型关系表、建筑与校区关系表  
  61.        for (int intRow = 0; intRow < dtAllBuildingCampusType.Rows.Count; intRow++)  
  62.         {  
  63.            //建筑ID  
  64.            string strBuildingID = Guid.NewGuid().ToString();  
  65.            //建筑代码  
  66.         string strBuildingCode= dtAllBuildingCampusType.Rows[intRow]["建筑代码"].ToString();  
  67.            //建筑名  
  68.            string strBuildingName = dtAllBuildingCampusType.Rows[intRow]["建筑名"].ToString();   
  69.            //建筑备注  
  70.            string strBuildingDescription=dtAllBuildingCampusType.Rows[intRow]["备注"].ToString();  
  71.            //建筑类型代码  
  72.            string strBuildingTypeCode = dtAllBuildingCampusType.Rows[intRow]["建筑类型代码"].ToString();  
  73.            //校区代码  
  74.            string strCampusCode=dtAllBuildingCampusType.Rows[intRow]["校区代码"].ToString();  
  75.   
  76.             
  77.            //根据建筑类型代码获取建筑类型ID  
  78.            BuildingTypeEntity enBuildingType = new BuildingTypeEntity();  
  79.            //建筑类型代码  
  80.            enBuildingType.BuildingTypeCode = strBuildingTypeCode;  
  81.            //建筑业务逻辑层,按建筑类型代码查询建筑类型ID  
  82.            DataTable dtBuildingType = new BuildingBLL().QueryBuildingTypeByCode(enBuildingType);  
  83.            //建筑类型ID为  
  84.            string strBuildingTypeID = dtBuildingType.Rows[0]["BuildingTypeID"].ToString();  
  85.   
  86.             
  87.            //根据校区代码获取校区ID  
  88.            CampusEntity enCampus = new CampusEntity();  
  89.            //校区代码  
  90.            enCampus.CampusCode = strCampusCode;  
  91.            //建筑业务逻辑层,按校区代码查询校区ID  
  92.            DataTable dtCampus = new BuildingBLL().QueryCampusByCode(enCampus);  
  93.            //校区ID  
  94.            string strCampusID=dtCampus.Rows[0]["CampusID"].ToString();  
  95.   
  96.            //添加建筑信息表的新行  
  97.            DataRow drAddBuilding = dtAddBuilding.NewRow();//注意这边创建dt的新行的方法。指定类型是DataRow而不是TableRow,然后不用new直接的用创建的DataTable下面的NewRow方法。  
  98.            //建筑信息表对应的各列值  
  99.            drAddBuilding["BuildingID"]=strBuildingID;  
  100.            drAddBuilding["BuildingCode"] = strBuildingCode;  
  101.            drAddBuilding["BuildingName"] = strBuildingName;  
  102.            drAddBuilding["IsAvailable"] = "是";  
  103.            drAddBuilding["Descriptions"] = strBuildingDescription;  
  104.            drAddBuilding["ActionType"] = null;  
  105.            drAddBuilding["ActionContent"] = null;  
  106.            drAddBuilding["ActionReason"] = null;  
  107.            drAddBuilding["Operator"] = null;  
  108.            drAddBuilding["SetDatetime"] = DateTime.Now; //当前日期时间  
  109.            dtAddBuilding.Rows.Add(drAddBuilding);  //将一整条数据写入表中  
  110.   
  111.            //添加建筑与建筑类型关系信息表的新行  
  112.            DataRow drAddBuildingType = dtAddBuildingType.NewRow();  
  113.            //建筑与建筑类型关系信息表对应的各列值  
  114.            drAddBuildingType["BuildingID"] = strBuildingID;  
  115.            drAddBuildingType["BuildingTypeID"] = strBuildingTypeID;  
  116.            drAddBuildingType["IsAvailable"] = "是";  
  117.            dtAddBuildingType.Rows.Add(drAddBuildingType); //将一整条数据写入表中  
  118.   
  119.            //添加建筑与校区关系信息表的新行  
  120.            DataRow drAddBuildingCampus = dtAddBuildingCampus.NewRow();  
  121.            //建筑与校区关系信息表对应的各列值  
  122.            drAddBuildingCampus["BuildingID"] = strBuildingID;  
  123.            drAddBuildingCampus["CampusID"] = strCampusID;  
  124.            drAddBuildingCampus["IsAvailable"] = "是";  
  125.            dtAddBuildingCampus.Rows.Add(drAddBuildingCampus); //将一整条数据写入表中  
  126.        }  
  127.          
  128.        //将各表加入DataSet中:建筑信息、建筑与建筑类型关系信息、建筑与校区关系信息  
  129.        dsBuildingCampusType.Tables.Add(dtAddBuilding);  
  130.        dsBuildingCampusType.Tables.Add(dtAddBuildingType);  
  131.        dsBuildingCampusType.Tables.Add(dtAddBuildingCampus);  
  132.   
  133.         
  134.   
  135.        //将DataSet中数据表导入数据库  
  136.        Boolean flagImportBuilding = buildingBLL.ImportBuiding(dsBuildingCampusType);  
  137.   
  138.        if (true==flagImportBuilding)  
  139.        {  
  140.            //导入成功,弹出提示  
  141.            Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('建筑信息导入成功!');</script>");  
  142.   
  143.   
  144.        }  
  145.        else  
  146.        {  
  147.            //导入失败,弹出提示  
  148.            Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('建筑信息导入失败!');</script>");  
  149.   
  150.   
  151.        }  
  152.    }  
  153.    #endregion  
 #region 批量导入建筑信息
    protected void btnImportBuilding_Click(object sender,EventArgs e) {
        //建筑业务逻辑层
        BuildingBLL buildingBLL = new BuildingBLL();
        //BLL层把Excel转化为datatable类
        CreateExcelDataBLL createExcelData = new CreateExcelDataBLL();
   
        //获取上传文件地址
        string url = fupImportBuilding.PostedFile.FileName.ToString();

        if (url == "")
        {
            //数据源为空,弹出提示:请选择Excel文件!
            Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('请选择Excel文件!');</script>");
            return;
        }

        string urlLocation = url.Substring(url.LastIndexOf("\") + 1);//获取文件名

        DataTable dtAllBuildingCampusType;
        //在系统中建文件夹up,并将excel文件另存
        this.fupImportBuilding.SaveAs(Server.MapPath("~\UploadFile") + "\" + urlLocation);//记录文件名到服务器相对应的文件夹中

        //获得文件路径
        string strpath = Server.MapPath("~\UploadFile") + "\" + urlLocation;
       
        //把上传的Excel转换为datatable
        dtAllBuildingCampusType = createExcelData.CreateExcelDataSource(strpath);

        DataSet dsBuildingCampusType = new DataSet("ds_BuilingCampusType"); //创建一个名为ds_BuilingCampusType的DataSet

        //手动创建的新数据表-建筑数据表
        DataTable dtAddBuilding = new DataTable("dt_AddBuilding"); //创建一个名为dt_AddBuilding的DataTalbe
        //为dt_AddBuilding表内建立Column(表头),添加数据列:建筑ID、建筑代码、建筑名、是否可用、备注、操作类型、操作内容、操作原因、操作人、操作时间
        dtAddBuilding.Columns.Add(new DataColumn("BuildingID", typeof(string)));
        dtAddBuilding.Columns.Add(new DataColumn("BuildingCode", typeof(string)));
        dtAddBuilding.Columns.Add(new DataColumn("BuildingName", typeof(string)));
        dtAddBuilding.Columns.Add(new DataColumn("IsAvailable", typeof(string)));
        dtAddBuilding.Columns.Add(new DataColumn("Descriptions",typeof(string)));
        dtAddBuilding.Columns.Add(new DataColumn("ActionType", typeof(string)));
        dtAddBuilding.Columns.Add(new DataColumn("ActionContent", typeof(string)));
        dtAddBuilding.Columns.Add(new DataColumn("ActionReason", typeof(string)));
        dtAddBuilding.Columns.Add(new DataColumn("Operator", typeof(string)));
        dtAddBuilding.Columns.Add(new DataColumn("SetDatetime", typeof(DateTime)));

        //手动创建的新数据表-建筑、建筑类型关系数据表
        DataTable dtAddBuildingType = new DataTable("dt_AddBuildingType"); //创建一个名为dt_AddBuildingType的DataTalbe
        //为dt_AddBuildingType表内建立Column(表头),添加数据列:建筑ID、建筑类型ID、是否可用
        dtAddBuildingType.Columns.Add(new DataColumn("BuildingID", typeof(string)));
        dtAddBuildingType.Columns.Add(new DataColumn("BuildingTypeID", typeof(string)));
        dtAddBuildingType.Columns.Add(new DataColumn("IsAvailable", typeof(string)));

        //手动创建的新数据表-建筑、校区关系数据表
        DataTable dtAddBuildingCampus = new DataTable("dt_AddBuildingCampus"); //创建一个名为dt_AddBuildingCampus的DataTalbe
        //为dt_AddBuildingCampus表内建立Column(表头),添加数据列:建筑ID、校区ID、是否可用
        dtAddBuildingCampus.Columns.Add(new DataColumn("BuildingID", typeof(string)));
        dtAddBuildingCampus.Columns.Add(new DataColumn("CampusID", typeof(string)));
        dtAddBuildingCampus.Columns.Add(new DataColumn("IsAvailable", typeof(string)));

        //从上传的Excel转换为的datatable表中取出数据,分别放入建筑信息表、建筑与建筑类型关系表、建筑与校区关系表
        for (int intRow = 0; intRow < dtAllBuildingCampusType.Rows.Count; intRow++)
			{
            //建筑ID
            string strBuildingID = Guid.NewGuid().ToString();
            //建筑代码
			string strBuildingCode= dtAllBuildingCampusType.Rows[intRow]["建筑代码"].ToString();
            //建筑名
            string strBuildingName = dtAllBuildingCampusType.Rows[intRow]["建筑名"].ToString();	
            //建筑备注
            string strBuildingDescription=dtAllBuildingCampusType.Rows[intRow]["备注"].ToString();
            //建筑类型代码
            string strBuildingTypeCode = dtAllBuildingCampusType.Rows[intRow]["建筑类型代码"].ToString();
            //校区代码
            string strCampusCode=dtAllBuildingCampusType.Rows[intRow]["校区代码"].ToString();

           
            //根据建筑类型代码获取建筑类型ID
            BuildingTypeEntity enBuildingType = new BuildingTypeEntity();
            //建筑类型代码
            enBuildingType.BuildingTypeCode = strBuildingTypeCode;
            //建筑业务逻辑层,按建筑类型代码查询建筑类型ID
            DataTable dtBuildingType = new BuildingBLL().QueryBuildingTypeByCode(enBuildingType);
            //建筑类型ID为
            string strBuildingTypeID = dtBuildingType.Rows[0]["BuildingTypeID"].ToString();

           
            //根据校区代码获取校区ID
            CampusEntity enCampus = new CampusEntity();
            //校区代码
            enCampus.CampusCode = strCampusCode;
            //建筑业务逻辑层,按校区代码查询校区ID
            DataTable dtCampus = new BuildingBLL().QueryCampusByCode(enCampus);
            //校区ID
            string strCampusID=dtCampus.Rows[0]["CampusID"].ToString();

            //添加建筑信息表的新行
            DataRow drAddBuilding = dtAddBuilding.NewRow();//注意这边创建dt的新行的方法。指定类型是DataRow而不是TableRow,然后不用new直接的用创建的DataTable下面的NewRow方法。
            //建筑信息表对应的各列值
            drAddBuilding["BuildingID"]=strBuildingID;
            drAddBuilding["BuildingCode"] = strBuildingCode;
            drAddBuilding["BuildingName"] = strBuildingName;
            drAddBuilding["IsAvailable"] = "是";
            drAddBuilding["Descriptions"] = strBuildingDescription;
            drAddBuilding["ActionType"] = null;
            drAddBuilding["ActionContent"] = null;
            drAddBuilding["ActionReason"] = null;
            drAddBuilding["Operator"] = null;
            drAddBuilding["SetDatetime"] = DateTime.Now; //当前日期时间
            dtAddBuilding.Rows.Add(drAddBuilding);  //将一整条数据写入表中

            //添加建筑与建筑类型关系信息表的新行
            DataRow drAddBuildingType = dtAddBuildingType.NewRow();
            //建筑与建筑类型关系信息表对应的各列值
            drAddBuildingType["BuildingID"] = strBuildingID;
            drAddBuildingType["BuildingTypeID"] = strBuildingTypeID;
            drAddBuildingType["IsAvailable"] = "是";
            dtAddBuildingType.Rows.Add(drAddBuildingType); //将一整条数据写入表中

            //添加建筑与校区关系信息表的新行
            DataRow drAddBuildingCampus = dtAddBuildingCampus.NewRow();
            //建筑与校区关系信息表对应的各列值
            drAddBuildingCampus["BuildingID"] = strBuildingID;
            drAddBuildingCampus["CampusID"] = strCampusID;
            drAddBuildingCampus["IsAvailable"] = "是";
            dtAddBuildingCampus.Rows.Add(drAddBuildingCampus); //将一整条数据写入表中
        }
        
        //将各表加入DataSet中:建筑信息、建筑与建筑类型关系信息、建筑与校区关系信息
        dsBuildingCampusType.Tables.Add(dtAddBuilding);
        dsBuildingCampusType.Tables.Add(dtAddBuildingType);
        dsBuildingCampusType.Tables.Add(dtAddBuildingCampus);

       

        //将DataSet中数据表导入数据库
        Boolean flagImportBuilding = buildingBLL.ImportBuiding(dsBuildingCampusType);

        if (true==flagImportBuilding)
        {
            //导入成功,弹出提示
            Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('建筑信息导入成功!');</script>");


        }
        else
        {
            //导入失败,弹出提示
            Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('建筑信息导入失败!');</script>");


        }
    }
    #endregion

   3.4.3 BLL层Excel转换成DataTable的类(MgrCreateExcelData.cs)

  1. /******************************************************************************* 
  2.  *文    件:CreateExcelDataBLL.cs 
  3.  *作    者:mzj 
  4.  *所属小组:评教小组 
  5.  *文件说明:基础系统-把excel转化为datatable 
  6.  *创建日期:2013年1月23日9:43:16 
  7.  *修改作者: 
  8.  *修改日期: 
  9.  *修改描述: 
  10.  *版 本 号:V1.0 
  11.  *版本号变更记录:      
  12. ********************************************************************************/  
  13.   
  14. using System;  
  15. using System.Collections.Generic;  
  16. using System.Linq;  
  17. using System.Text;  
  18.   
  19. //引用各命名空间  
  20. using System.Data;  
  21. using System.Data.OleDb;  
  22. using System.Data.SqlClient;  
  23. using System.IO;  
  24.   
  25. namespace TeachSystem.BLL.CreateExcelDataBLL  
  26. {  
  27.     public class CreateExcelDataBLL  
  28.     {  
  29.         //构造方法  
  30.         public CreateExcelDataBLL()  
  31.         {  
  32.   
  33.         }  
  34.         /// <summary>  
  35.         /// 传入excel路径,转换为datatable  
  36.         /// </summary>  
  37.         /// <param name="url"></param>  
  38.         /// <returns></returns>  
  39.         public DataTable CreateExcelDataSource(string url)  
  40.         {  
  41.             //定义一个DataTable数据表  
  42.             DataTable dt = null;  
  43.   
  44.             //获得excel数据  
  45.             string connetionStr = "Provider=Microsoft.Jet.OleDb.4.0;" + "data source=" + url + ";Extended Properties='Excel 8.0; HDR=YES; IMEX=1'";  
  46.             //从Excel表的Sheet1单元格获取数据  
  47.             string strSql = "select * from [Sheet1$]";  
  48.             OleDbConnection oleConn = new OleDbConnection(connetionStr);  
  49.   
  50.             OleDbDataAdapter oleAdapter = new OleDbDataAdapter(strSql, connetionStr);  
  51.             try  
  52.             {  
  53.                 //把Excel数据填充给DataTable  
  54.                 dt = new DataTable();  
  55.                 oleAdapter.Fill(dt);  
  56.                 //返回数据表  
  57.                 return dt;  
  58.             }  
  59.             catch (Exception ex)  
  60.             {  
  61.                 throw ex;  
  62.             }  
  63.             finally  
  64.             {  
  65.                 oleAdapter.Dispose();  
  66.                 oleConn.Close();  
  67.                 oleConn.Dispose();  
  68.                 //删除上传的Excel文件(因为该文件的存在会占用多余的网站空间)  
  69.                 if (File.Exists(url))  
  70.                 {  
  71.                     File.Delete(url);  
  72.                 }  
  73.             }  
  74.         }  
  75.     }  
  76. }  
/*******************************************************************************
 *文    件:CreateExcelDataBLL.cs
 *作    者:mzj
 *所属小组:评教小组
 *文件说明:基础系统-把excel转化为datatable
 *创建日期:2013年1月23日9:43:16
 *修改作者:
 *修改日期:
 *修改描述:
 *版 本 号:V1.0
 *版本号变更记录:     
********************************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

//引用各命名空间
using System.Data;
using System.Data.OleDb;
using System.Data.SqlClient;
using System.IO;

namespace TeachSystem.BLL.CreateExcelDataBLL
{
    public class CreateExcelDataBLL
    {
        //构造方法
        public CreateExcelDataBLL()
        {

        }
        /// <summary>
        /// 传入excel路径,转换为datatable
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public DataTable CreateExcelDataSource(string url)
        {
            //定义一个DataTable数据表
            DataTable dt = null;

            //获得excel数据
            string connetionStr = "Provider=Microsoft.Jet.OleDb.4.0;" + "data source=" + url + ";Extended Properties='Excel 8.0; HDR=YES; IMEX=1'";
            //从Excel表的Sheet1单元格获取数据
            string strSql = "select * from [Sheet1$]";
            OleDbConnection oleConn = new OleDbConnection(connetionStr);

            OleDbDataAdapter oleAdapter = new OleDbDataAdapter(strSql, connetionStr);
            try
            {
                //把Excel数据填充给DataTable
                dt = new DataTable();
                oleAdapter.Fill(dt);
                //返回数据表
                return dt;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                oleAdapter.Dispose();
                oleConn.Close();
                oleConn.Dispose();
                //删除上传的Excel文件(因为该文件的存在会占用多余的网站空间)
                if (File.Exists(url))
                {
                    File.Delete(url);
                }
            }
        }
    }
}

   至此批量向数据库多张表导入数据的功能已完成了,对想数据库表导入的数据的合法性还需要自己通过代码进进行判断!

原文地址:https://www.cnblogs.com/TJessica/p/6836073.html