今天接到一个需求,实现一个小功能—导入Excel,想想诸位活跃于.NET平台上的兄弟们,其中应该有相当一部分是从事如信息系统类开发的,所以小弟在这里姑且臭屁一下导入Excel的几种实现方法,如有错误之处,烦请大虾指正。

第一步呢当然是将Excel中的数据导入进DataTable里面,这一步是很简单的,贴下Code。之后开始讨论如何将DataTable中的这些数据放进数据库里面:

代码

// 读取Excel
    public static DataTable GetExcelFileData(string filePath)
    {
        OleDbDataAdapter oleAdp = new OleDbDataAdapter();
        OleDbConnection oleCon = new OleDbConnection();
        string strCon = "Provider=Microsoft.Jet.oleDb.4.0;data source=" + filePath + ";Extended Properties='Excel 8.0;HDR=Yes;IMEX=1'";
        try
        {
            DataTable dt = new DataTable();
            oleCon.ConnectionString = strCon;
            oleCon.Open();
            DataTable table = oleCon.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
            string sheetName = table.Rows[0][2].ToString();
            string sqlStr = "Select * From [" + sheetName + "]";
            oleAdp = new OleDbDataAdapter(sqlStr, oleCon);
            oleAdp.Fill(dt);
            oleCon.Close();
            return dt;
        }
        catch (Exception ex)
        {
            throw ex;
        }
        finally
        {
            oleAdp = null;
            oleCon = null;
        }
    }

将DataTable中的数据放到到数据库大概有如下几种实现方法:

1、 Excel导入 — 循环执行插入操作

这种方法问题颇多,而且效率很低,需要一次次在循环里面执行插入操作,我以往做法是先定义一个Insert语句,然后在循环里面不断的改变Insert 语句中参数的值,执行插入操作,当然这里是使用了Microsoft 提供的SqLHelper的ExecuteNonQuery执行Insert语句。这样做的问题是每一个Insert语句都要执行一次数据库的连接,而这种连接系统维护了一个对象池,每一个连接都先从对象池中取出,如果对象池中没有将创建新对象,并加入对象池。而对象池中的无用对象需要一定的时间后才能释放。所以如果你在短时间内使用的连接很多的话,就有可能造成对象池满员。你再需要连接的话就需要等待释放,而你等待的时间远比释放的时间短,这时系统就会告诉你连接超时,系统抛出异常了,但是即便不抛出异常,这样反复的打开关闭数据的连接,也极大的影响了系统的性能。

当然也有很多朋友没有使用SqLHelper 去处理这样的数据导入操作,而是将数据库连接放在了循环的方面,等循环里面的Insert语句执行完了,再释放连接,这样做的效率虽比上面的方法效率高些,但同样的问题就是为插入的每个记录执行一次与数据库服务器的往返,如果数据量大的话,对系统的性能同样是一个挑战。

2、 Excel导入 — 使用SqlBulkCopy的WriteToServer方法,批量导入数据

这种做法的缺点是要求EXCEL的格式必须与要导入的Table完全一致而且还要删除多余的Sheet,但是他在性能上优于上面的方法,它可以通过让DataSet或是DataReader中大量的数据通过数据流直接进行装载,然后可以将这些记录添加到指定的数据表中。

使用方法:

     WriteToServer(DataTable)写入数据表

      WriteToServer(DataRow)批次写入数据行

      WriteToServer(DataTable,DataRowState)按行状态写入数据库表

      WriteToServer(DataReader)写入DataReader对象

同时SqlBulkCopy对象有个BatchSize这两个属性,BatchSize属性是非常重要的,程序性能如何主要就依靠着它。 BatchSize的意思就是同每一批次中的行数,在每一批次结束时,就将该批次中的行发送到数据库。譬如将BatchSize属性设置成了500,其意思就是每读出500行数据就将他们发送到数据库从而执行批量复制的操作。 BatchSize的默认值是“1”,其意思就是把每一行作为一个批次发送到数据库

这种做法,也是网上大多数朋友所推荐的的数据移植方法。

3、 Excel导入 — 使用Linq提供的InsertAllOnSubmit方法(这里将详细介绍这种方法)

InsertAllOnSubmit方法是将一个实体集合添加到datacontext对象中,并在SubmitChange()的时候执行更改,这里我还没来的及做性能测试,有空一定补上,先贴上Code:

代码

public static void excelInsertDataForInsert(DataTable dtExcel,string UserName)
    {
        using (MAUCPODataContext db = new MAUCPODataContext())
        {
            Dictionary<string, string> listPN_Lavel=getPN_Lave();
            var query = from q in dtExcel.AsEnumerable()
                        where !string.IsNullOrEmpty(q["POPGI_T"].ToString().Trim()) &&
                              !string.IsNullOrEmpty(q["PONo"].ToString().Trim()) &&
                              !string.IsNullOrEmpty(q["PN"].ToString().Trim()) &&
                              !string.IsNullOrEmpty(q["QTY"].ToString().Trim()) &&
                              !string.IsNullOrEmpty(q["Price"].ToString().Trim())
                        select new
                        {
                            POPGI_T = q["POPGI_T"].ToString().Trim(),
                            PONo = q["PONo"].ToString().Trim(),
                            PN = q["PN"].ToString().Trim(),
                            QTY = q["QTY"].ToString().Trim(),
                            Price = q["Price"].ToString().Trim()
                        };
            List<MAUCPO> listEntity = new List<MAUCPO>();
            foreach (var q in query)
            {
                MAUCPO Entity = new MAUCPO();
                Entity.CREATE_t = DateTime.Now;
                Entity.CreateBy = UserName;
                Entity.PN = q.PN;
                Entity.PONo = q.PONo;
                Entity.POPGI_T = DateTime.Parse(q.POPGI_T);
                Entity.Price = decimal.Parse(q.Price);
                Entity.Priority = int.Parse(listPN_Lavel[q.PN]);
                Entity.ProcessFlag = 'N';
                Entity.QTY = int.Parse(q.QTY);
                listEntity.Add(Entity);
            }
            db.MAUCPO.InsertAllOnSubmit(listEntity);
            db.SubmitChanges();
        }
    }

首先需要将你传入的DataTable转换成Enumerable类型,这样才能执行Linq查询,这里where的条件是为了过滤掉DataTable中的空行,select中的内容是取出DataTable中对应列的数据,最后将查询出来的数据转换成泛型类型listEntity,然后调用InsertAllOnSubmit(listEntity)方法,执行批量插入操作。

至于InsertAllOnSubmit的效率问题,网上也没有搜到太详细的介绍,有时间一定用要测下大数据量下的InsertAllOnSubmit方法效率如何。

转载于:https://www.cnblogs.com/yangtongnet/archive/2010/05/24/1742853.html

Linq杂谈之 — Linq导入Excel相关推荐

  1. 转:[Asp.net]常见数据导入Excel,Excel数据导入数据库解决方案,总有一款适合你!...

    引言 项目中常用到将数据导入Excel,将Excel中的数据导入数据库的功能,曾经也查找过相关的内容,将曾经用过的方案总结一下. 方案一 NPOI NPOI 是 POI 项目的 .NET 版本.POI ...

  2. asp.net 导入excel显示进度

    这几天在做个导入excel的上传页面,由于数据量太大,要显示个进度条,本人不懂jquery,所以百度完再经过调整之后完成了,如果告诉别人只是为了显示个进度条而弄个多线程,还要根据session的机制模 ...

  3. C#导入Excel数据(简单)

    备注: Demo项目创建的控制器为.NET Core3.1框架 1.控制台应用程序代码 using System; using System.IO;namespace Excel_Import {cl ...

  4. C#光功率计_扫码器导入excel

    公司要求扫码器读入编码,然后光功率计取出数值,等完成后把两个数据导入excel 用了将近一个月 时间  以前在学校一直想学一款上位机的,但是C#,LABVIEW,QT,VC,deliphi 选择太多了 ...

  5. NPOI导出和导入Excel,Word和PDF

    Models文件夹 NPOIModel.cs namespace NPOItest.Models {using System;using System.Data.Entity;using System ...

  6. POI操作Excel实例之将文本内容格式化导入Excel

    这里介绍一个最近写的小程序,对从微博爬取的用户数据的.TXT文档,进行逐行导入Excel表格中,下面是输入文档和输出表格: 微博数据.txt 3891186595 15关注 125粉丝 2402微博 ...

  7. Linq初级班 Linq To XML体验(基础篇)

    LINQ To XML体验(基础) 这两天开始学习LINQ to XML的知识,我会继续把自己的感想和示例发布给初学者们学习的,一样欢迎高手们多多指点,请勿使用过激语言,针锋相对,我是个初学者,自知还 ...

  8. word录入表单数据 java 导入系统,java导入excel | 怎么把excel中的数据批量导入到word中的表格中...

    用javascript怎么实现把excel中的数据批量导入到数据库表中 这个js不能直接实现吧 我们程序用到 先读取excel内容转换成数组 然后放到页面上 再提交表单 储存 MySql如何批量添加数 ...

  9. python绘制动态图表怎么存下来_用python如何实现导入excel数据后自动生成图表?python如何实现交互式动态图表?...

    这个需求涉及的环节太多了.导入excel文件,获取数据 -- 需要xlrd模块把数据导入python 2. 设定输出图表类型 -- 需要matplot模块.根据数据复杂度,可能需要ETL,那么需要pa ...

最新文章

  1. 推荐一款学习R的APP
  2. 离散问题的最大似然估计
  3. 贝叶斯决策思想的应用与延伸
  4. Android PopupWindow使用,下拉式PopupWindow,底部式PopupWindow
  5. android显示view在屏幕中间,android – 如何在屏幕中央显示imageview?
  6. 基于单片机的自动加热水壶控制器代码_应用于实时温度控制的单片机设计
  7. sans serif字体_30种免费的Sans Serif字体下载
  8. 使用计算机自带的wifi,电脑的自带无线网卡你知道怎么用吗?赶紧学习一下
  9. sofa与springboot的入门案例
  10. 5.19C++:标识符、关键字、多文件结构、exter、编译预处理
  11. 等比矩阵求和-POJ3233
  12. 制作手札---RPG是怎样做成的 (三)
  13. 大数据—— Clickhouse 介绍与引擎的使用
  14. 【健身】程序员也应该知道的胸背体态矫正锻炼技巧(中)
  15. 【架构师-系统设计】理解分布式系统的CAP和BASE理论
  16. Activiti实战. 1.2工作流基础
  17. 【Spring】1.核心原理解析
  18. mpvue 如何使用腾讯视频插件?
  19. 手把手教你在centos上配置Django项目(超详细步骤)
  20. CSS——文字对齐方式

热门文章

  1. 详解rel=”nofollow”的用法与意义
  2. 解决压缩包跨平台解压缩的中文乱码问题
  3. 利用pandas高维作图
  4. 大数——大数阶乘(hdu1042)
  5. double free or corruption 错误解决办法
  6. 【AI视野·今日CV 计算机视觉论文速览 第188期】Wed, 23 Dec 2020
  7. 【notebook】常用在线notebook总结
  8. 继承演练 c# 1613706361
  9. 泛型类 0104 c#
  10. 断开式绑定ComboBox 关键命令 1201