在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
上篇提要: 接到一个需求,实现一个小功能—导入Excel,想想诸位活跃于.NET平台上的兄弟们,其中应该有相当一部分是从事如信息系统类开发的,所以小弟在这里姑且臭屁一下导入Excel的几种实现方法,如有错误之处,烦请大虾指正。 1、 Excel导入 — 循环执行插入操作,批量导入数据 2、 Excel导入 — 使用Linq提供的InsertAllOnSubmit方法,批量导入数据 3、 Excel导入 — 使用SqlBulkCopy的WriteToServer方法,批量导入数据 本篇重点: 在上一篇中谈到了.NET的三种数据拷贝方法,但是并没有做性能测试,今天闲来无事,索性做下性能测试,测试数据量10W条。 机器配置及开发工具:CPU/P E5200 2.5GHZ 内存/2G 操作系统/Microsoft WINDOWS XP SP3 数据库/Microsoft SQL SERVER 2005 Framework/.Net Framework 3.5 SP1 开发工具/Microsoft VS 2008 SP1 原始数据表:IPInfo[IPid(Identity),IPFrom,IPTo,IPLocation,IPCity,IPToNumber,IPFromNumber] 数据条数:345000条(这里用10W条来测试)
导入数据表:IPInfo1[IPid(Identity),IPFrom,IPTo,IPLocation,IPCity,IPToNumber,IPFromNumber] 数据条数:0条,每次导入前,均清空IPInfo1表中数据 首先是测试第一种方法,也就是直接用ADO.NET执行循环插入操作,批量导入数据,这里先贴上CODE:
代码
public static void InsertToIPInfo1_ADO(DataTable dt)
{ using (SqlConnection conn = new SqlConnection("Data Source=WSH-S0904003;Initial Catalog=GroupSell;User ID=sa;Password=123")) { conn.Open(); string strSql = "Insert Into IPInfo1(IPFrom,IPTo,IPLocation,IPCity,IPToNumber,IPFromNumber) values (@IPFrom,@IPTo,@IPLocation,@IPCity,@IPToNumber,@IPFromNumber)"; for (int i = 0; i < dt.Rows.Count; i++) { SqlCommand Comm = conn.CreateCommand(); Comm.CommandText = strSql; Comm.CommandType = CommandType.Text; Comm.Parameters.Add("@IPFrom", SqlDbType.VarChar).Value = dt.Rows[i]["IPFrom"]; Comm.Parameters.Add("@IPTo", SqlDbType.VarChar).Value = dt.Rows[i]["IPTo"]; Comm.Parameters.Add("@IPLocation", SqlDbType.VarChar).Value = dt.Rows[i]["IPLocation"]; Comm.Parameters.Add("@IPCity", SqlDbType.VarChar).Value = dt.Rows[i]["IPCity"]; Comm.Parameters.Add("@IPToNumber", SqlDbType.VarChar).Value = dt.Rows[i]["IPToNumber"]; Comm.Parameters.Add("@IPFromNumber", SqlDbType.VarChar).Value = dt.Rows[i]["IPFromNumber"]; Comm.ExecuteNonQuery(); } } }
下面是调用方法:
代码
class Program
{ static void Main(string[] args) { //取10W数据 DataTable dt = IpInfo_BLL.get10WData(); //开始时间 Console.WriteLine(DateTime.Now.ToString()); DateTime db = DateTime.Now; //Linq InsertAllOnSubmit() IpInfo_BLL.InsertToIPInfo1_Linq(dt); //ADO Insert //IpInfo_BLL.InsertToIPInfo1_ADO(dt); //SqlBulkCopy //IpInfo_BLL.InsertToIPInfo1_SqlCopy(dt); //时间差值 Console.WriteLine(DateTime.Now - db); } }
下面是取DataTable数据的方法,索性也贴上来:
代码
public static DataTable get10WData()
{ using (SqlConnection conn = new SqlConnection("Data Source=WSH-S0904003;Initial Catalog=GroupSell;User ID=sa;Password=123")) { string strSql = "select top(100000) * from IPInfo"; DataSet ds = new DataSet(); SqlDataAdapter adaper = new SqlDataAdapter(strSql, conn); adaper.Fill(ds); return ds.Tables[0]; } }
下面上结果: 耗时2分34秒8281250(小数部分) 下面我们测试第二种方法也就是使用Linq的InsertAllOnSubmit的方法实现数据拷贝:
代码
public static void InsertToIPInfo1_Linq(DataTable dt)
{ using (IPInfo1DataContext db = new IPInfo1DataContext()) { var query = from q in dt.AsEnumerable() select new { IPFrom = q["IPFrom"].ToString().Trim(), IPTo = q["IPTo"].ToString().Trim(), IPLocation = q["IPLocation"].ToString().Trim(), IPCity = q["IPCity"].ToString().Trim(), IPToNumber = q["IPToNumber"].ToString().Trim(), IPFromNumber = q["IPFromNumber"].ToString().Trim() }; List<IPInfo1> list = new List<IPInfo1>(); foreach (var q in query) { IPInfo1 Entity = new IPInfo1(); Entity.IPCity = q.IPCity; Entity.IPFrom = q.IPFrom; Entity.IPFromNumber = q.IPFromNumber; Entity.IPLocation = q.IPLocation; Entity.IPTo = q.IPTo; Entity.IPToNumber = q.IPToNumber; list.Add(Entity); } db.IPInfo1.InsertAllOnSubmit(list); db.SubmitChanges(); } }
下面上结果: 耗时1分50秒4843750(小数部分) 下面我们来看第三种方法,使用SqlBulkCopy的WriteToServer方法,批量导入数据,大家要做好心理准备哦!
代码
public static void InsertToIPInfo1_SqlCopy(DataTable dt)
{ using (SqlBulkCopy bulkCopy = new SqlBulkCopy("Data Source=WSH-S0904003;Initial Catalog=GroupSell;User ID=sa;Password=123")) { bulkCopy.DestinationTableName = "IPInfo1"; bulkCopy.WriteToServer(dt); } }
下面上测试结果: 耗时:0分5秒9532774(小数部分) 测试总结: 测试结果显示选择使用ADO.NET的基本方法来复制大批数据是错误的,也是耗时最长的,这里的测试是在本机进行的,如果数据库的Server跟网站的Server不在同一台服务器上,将会花费更多的时间。当然Linq的效率要比前者高些,略高2/5,但Linq操作起来便捷,对效率要求不是太苛刻的朋友,用Linq导入数据也是一种不错的选择,当然了,最棒的方法还是SqlBulkCopy,但是这种做法的缺点是要求EXCEL的格式必须与要导入的Table完全一致而且还要删除多余的Sheet。所以测试结果如上,朋友们可以视情况而定。 |
请发表评论