随笔 - 31  文章 - 1 评论 - 191 trackbacks - 3
<2007年12月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

欢迎访问我的非技术博客:
http://Moosdau.blog.163.com

与我联系

搜索

 

常用链接

留言簿(3)

随笔分类(30)

随笔档案(31)

最新评论

阅读排行榜

评论排行榜

假设一个常见的场景先吧----实际也是我当前的场景-----把一个excel 文件导入到数据库. 这实在是一个常见的功能,但是,没想到的是, 我着实费了一把劲.

实际上,我以前写的有现成的函数来完成这个工作, 但是, 可惜那函数只能在VS2005 下工作, 在2003下面无效,无效的原因是,vs2003 的DataTable.Rows[i].SetAdded() 方法不存在. 也就是说, 你没有办法去更改一行的RowState, 而从excel 读到的dataTable的 行状态"默认" 是unChanged.

如果不信, 你也可以尝试去google或百度上搜一下试试看, 关于这个功能的贴子真是少得可怜,大约大家都换用vs2005了吧, 我找了半天, 零零碎碎地找到一些信息, 这些信息都指向DataTable.GetChanges(RowState) 函数, 由于都是语焉不详, 所以我高兴地认为, 这个函数能将表的所有行的状态都设置为参数所指定的RowState, 就像我原来的函数用一个for循环为每一行调用SetAdded 的效果一样, 我一边还惭愧, 以前用了那么笨的办法. 然而心底却在奇怪, 微软怎么会起了这么笨的一个函数名.

一番测试后, 终于弄明白原来不是微软笨,而是我弄错了, GetChanges函数果然是用来Get, 而不是set的, 它返回母表中指定状态的行组成的子表, 也就是说, 刚才的查找白费了.

再找了一会儿, 借助于Mitch Milam 先生十分专业的一篇文章, 终于找到了正确的solution, 这篇文章的url:
http://blogs.infinite-x.net/2006/09/21/the-saga-of-net-dataadapterupdate-and-multiple-tables/print/
说它专业, 是因为这篇文章几乎是以正规科技论文的格式来写的, 虽然我自己写论文的时候很讨厌麻烦的格式, 但是阅读的时候, 却不得不承认, 这种严谨的格式读起来实在是愉快地多. ----废话少说, 问题的关键在于行状态, 从excel 读取后成了unchanged, 而且又无法修改, 问题就在于读取. 原来数据适配器有一个AcceptChangesDuringFill 属性, 这个属性默认为true, 所以调用Fill 方法后, 它就自动地AcceptChange了 , 然后行状态就变成unchanged了, 只要把这个属性置为false, fill 后, 就可以保持行状态为Added, 然后在update 函数里就不需要考虑行状态了.

以下为不太熟悉这两种操作的朋友列出源代码, 为了阅读方便,去掉了错误检查部分的代码,但在实际应用中, try语句是不可缺少的:
<0>调用代码:
1string path="upload";
2DataTable dt=ImportFromExcel(path);
3string selectCommand="SELECT * FROM T1";
4UpdateToDataBase(selectCommand,dt);

<1> 从excel 读取数据
 1DataTable ImportFromExcel(string path)
 2{
 3    path=Server.MapPath(path);
 4    upload1.PostFile.SaveAs(path);
 5
 6 string connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + path +";Extended Properties='Excel 8.0;HDR=yes;IMEX=1;'";
 7    string selectCommand = " SELECT * FROM [Sheet1$] ";
 8   DataTable dt=new DataTable();
 9
10    System.Data.OleDb.OleDbConnection conn=new System.Data.OleDb.OleDbConnection(connString);
11    conn.Open();
12    System.Data.OleDb.OleDbCommand cmd = new System.Data.OleDb.OleDbCommand(selectCommand, conn);
13    System.Data.OleDb.OleDbDataAdapter adt = new System.Data.OleDb.OleDbDataAdapter(cmd);
14    adt.AcceptChangesDuringFill=false;
15    adt.Fill(dt);
16    conn.Close();
17    System.IO.File.Delete(path);
18    return dt;
19
20}
这里面的trick 就是第14 行.

<2>提交DataTable 到数据库

 

 1void UpdateToDataBase(string sql,DataTable dt)
 2{
 3    string connString=GetConnectionString();
 4
 5   System.Data.SqlClient.SqlConnection con = new System.Data.SqlClient.SqlConnection(connString);
 6   System.Data.SqlClient.SqlDataAdapter adt = new System.Data.SqlClient.SqlDataAdapter(sql, con);
 7   System.Data.SqlClient.SqlCommandBuilder builder = new System.Data.SqlClient.SqlCommandBuilder(adt);
 8    adt.InsertCommand=builder.GetInsertCommand();
 9    con.Open();
10    adt.Update(dt).ToString();
11    con.Close();
12}

13
没有永恒的事
一切都在不断重复
我热爱这个世界
但绝不骄纵了它
posted on 2007-12-21 13:10 木刀 阅读(386) 评论(0)  编辑 收藏 网摘 所属分类: asp.net 点滴

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
Google站内搜索

China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
近千种 9-95 新二手计算图书火热销售中!
开发者征途系统新作:《设计模式——基于C#的工程化实现及扩展》



相关文章:

相关链接: