注册 登录
编程论坛 C# 论坛

C#.NET中存取数据库入门贴(ADO.NET)

师妃暄 发布于 2008-07-28 10:42, 18315 次点击
*/ --------------------------------------------------------------------------------------
*/ 出自: 编程中国 https://www.bccn.net
*/ 作者: 师妃暄 E-mail:shifeixuan@ QQ:591608560
*/ 时间: 2008-7-28 编程论坛首发
*/ 声明: 尊重作者劳动,转载请保留本段文字
*/ --------------------------------------------------------------------------------------

首先想告诉大家的是确实是.NET知识体系中的重中之重。因为微软.NET平台最适合的就是做管理系统(尤其是ERP),这些系统核心思想就是收集,处理,保存数据。这必定要依靠与数据库进行交互。

经常见到坛子里新手们对如何操作数据库感到比较困惑,这是很正常的。这里我分享下我的一些经验和知识,企图用最直白最直接的描述让大家了解如何存取数据库。希望以后大家见到此贴能助一臂之力。

也许刚接触.NET的朋友会问:与C#.NET或者到底是什么关系。在我看来,他们是一个整体。当我们用C#.NET写一程序时,这个程序可能涉及到界面的创建,数据的存取,业务的逻辑等等。我们就把其中连接数据库,执行SQL语句,获得数据集,再逐条获得数据,再关闭数据库的一段过程单独拿出来给个名称叫做

中连接数据库有两种方式,一种是要持续保持连接的。另一种是不需要持续保持连接的。

我们先来看第一种方式:为什么说是要持续保持连接的呢?就是说从打开数据库到关闭数据库这整个过程,都必须是程序与后端的数据库保持着连接。最明显的特征就是用到了XXXDataReader这个对象来访问数据。
来看一个简单的例子(MS SQLServer):用到别忘来在文件中引用命名空间using System.Data.SqlClient;

程序代码:
string  ConnectionString = "server=.;database=pubs;user=sa;pwd="; //这是获得连接数据库的字符串,不用过多解释了吧- -!
SqlConnection conn = new SqlConnection(ConnectionString);
conn.Open();                                                      //创建连接数据库的对象并且打开数据库

string  sqlstr= "SELECT * FROM authors";

SqlCommand cmd = new SqlCommand(sqlstr,conn);                     //创建执行SQL语句的对象.注意两个参数
= CommandType.Text;                               //指定SQL命令的类型。如果是存储过程的话,这里写CommandType.StoredProcedure;
                             
SqlDataReader reader = cmd.ExecuteReader();                       //创建有持续连接的读取数据的对象,并接收执行命令。
while (reader.Read())
{
     //每reader.Read()一下,就读取了一行数据,可以对这行数据进行操作了
}
conn.Close();                                                     //关闭数据库连接


现在如果感觉有点蒙,别急,听我慢慢解析。让我们再来看看第二种连接方式。这种方式是当我们执行完了SQL命令后,肯定会返回数据集的对吧?(当然是指SELECT命令),这个时候要在本地创建一个数据接收对象,这个对象是在内存中的。一次性接受完毕后,关闭数据库连接。这时我们只需要对本地数据集进行操作就可以了。与后台真正的数据库没有任何关系了。有人会问,这个东东到底是个啥玩意?这就是传说中的DataSet。它是多张数据表的集合,也就是说当我们用SqlCommand命令执行完毕后,数据集如果是一张表,DataSet接收后就是一张表,如果是多张表,DataSet中就会有多张表。只不过是用DataSet[0].DataSet[1]这样来取就可以了。我们来看一个例子:
程序代码:
string  ConnectionString = "server=.;database=pubs;user=sa;pwd="; //这是获得连接数据库的字符串,不用过多解释了吧- -!
SqlConnection conn = new SqlConnection(ConnectionString);
conn.Open();                                                      //创建连接数据库的对象并且打开数据库

string  sqlstr= "SELECT * FROM authors";

SqlCommand cmd = new SqlCommand(sqlstr,conn);                     //创建执行SQL语句的对象.注意两个参数
= CommandType.Text;                               //指定SQL命令的类型。如果是存储过程的话,这里写CommandType.StoredProcedure;
                             
DataSet ds= new DataSet();                                        //创建无持续连接的读取数据的对象
SqlDataAdapter ada = new SqlDataAdapter();
ada.SelectCommand = cmd;
ada.Fill(ds);
conn.Close();                                                     //关闭数据库连接


//后面所有对数据库的操作都是在连接关闭的情况下进行的....

细心的读者会发现,怎么多出了三行,SqlDataAdapter是什么东东。这就是第二种连接方式最大的特征--数据适配器。简单的说,这个适配器就是后台数据库与本地内存中的DataSet连接的通道。我们可以把后台数据库想象成楼顶上的太阳能热水箱,本地内存的DataSet想象成家里浴室的喷头。喷头的水怎么来的啊?当然是靠管道从楼顶得到的嘛,这个SqlDataAdapter就充当着管道的角色,千万别把它想复杂了。ada.Fill(ds);就是把结果填充到本地的方法。

[[it] 本帖最后由 师妃暄 于 2008-7-28 22:01 编辑 [/it]]
72 回复
#2
师妃暄2008-07-28 10:44
好,现在基本的写法已经可以搞清楚了。大家可以先写两个简单的程序试试看....

有朋友会问,这两种方式各有什么利弊?我怎么知道哪个时候用哪种方式呢?很好,谁这样问,说明你很会学习很会思考

用持续连接方式的好处是DataReader的读取效率非常快,是DataSet的几倍。但它的劣势也很明显,一是持续保持数据库连接,必然要抢占数据库的资源,如果一个数据库连接上限是10人,这就非常糟糕了。另一方面DataReaderd虽然效率高。但只读向前,很不灵活。
而非持续连接方式的好处是数据读取灵活,操作方便。而且不占用数据库资源。还有就是可以灵活绑定控件(这个以后再讲)

大家是不是经常看高手写的代码?会发现这些高手们的代码清晰简洁,一反常规,看起来非常酷?其实也没什么高深的,下面我就说说如何优化这段代码,看起来有点专业水平。

首先优化【连接数据库的字符串】,例子中那样写是很菜的。一般都写到配置文件中。在工程中添加一个.config文件(项目中是App.config.网站中是web.config)然后添加这么一段
程序代码:
<configuration>
  <connectionStrings>
    <add name="MaSqlConnection" providerName="System.Data.SqlClient" connectionString="server=.;database=pubs;user=sa;pwd="/>
  </connectionStrings>
</configuration>


这样,这个字符串在整个项目中都可以用,只需写一次就可以了。怎么在程序中引用呢?
string connstr = ConfigurationManager.ConnectionStrings["MaSqlConnection"].ConnectionString;
就可以了。注意引用命名空间using System.Configuration(项目要添加相关引用,网站中不需要)

接下来,我们用using(){}管理下连接对象
我们把例子的代码这样调整下
程序代码:
string  ConnectionString = "server=.;database=pubs;user=sa;pwd="; //这是获得连接数据库的字符串,不用过多解释了吧- -!
using(SqlConnection conn = new SqlConnection(ConnectionString))
{
         conn.Open();                                                      //创建连接数据库的对象并且打开数据库
         string  sqlstr= "SELECT * FROM authors";
         SqlCommand cmd = new SqlCommand(sqlstr,conn);                     //创建执行SQL语句的对象.注意两个参数
          = CommandType.Text;                             
         SqlDataReader reader = cmd.ExecuteReader();      
         while (reader.Read())
         {
              //每reader.Read()一下,就读取了一行数据,可以对这行数据进行操作了
         }
}


用using来管理,系统机制可以在适当的时候关闭掉数据库的连接,不需要手动close()
如果用到了适配器SqlDataAdapter ,还可以省略掉Open();很好用的功能

再来看有SqlDataAdapter的情况,还可以继续优化代码。可以省略掉SqlCommand 所有相关的,代码非常简单
通过这三步优化,上面的例子可以写成这样:
程序代码:
string connstr = ConfigurationManager.ConnectionStrings["MaSqlConnection"].ConnectionString;
string sqlstr = "SELECT * FROM authors";
DataSet ds = new DataSet();
using (SqlConnection conn = new SqlConnection(connstr))
{
     SqlDataAdapter adapter = new SqlDataAdapter(sqlstr, conn);
     adapter.Fill(ds);
}


上班时间,忙里偷闲- -!终于写完了。。。也完成了我的一个心愿,上次再群里就说要写个ADO的专题,今天才写出来。呵呵。

[[it] 本帖最后由 师妃暄 于 2008-9-9 12:39 编辑 [/it]]
#3
redcar2008-07-28 17:01
楼主,貌似现在MS力推LINQ哈
最近在研究LINQ,貌似就是资源占用大点,但是操作比较简单
#4
师妃暄2008-07-28 17:04
LINQ是C#3.0推荐的知识
早点研究很不错
#5
redcar2008-07-28 17:09
期待美女写个LINQ专题
#6
恶魔跟班2008-07-28 17:21
呵呵,写得比书上的好!
我才学C#的,问一下using是什么,怎么用的啊?
#7
redcar2008-07-28 17:25
using就是使用,顾名思义了.
比如,你要使用MM,就这样写
using mm;
然后mm下面的所有功能就可以直接调用了.否则,你必须这样
mm.kiss;
mm.ml;
using了之后就可以这样
kiss;
ml;

还有1种用法就是
using(mm)
{xxoo}
这个的好处就是会自动释放资源,不要手动指定
mm.dispose;
#8
师妃暄2008-07-28 17:33
我的2楼有using的解释的
#9
恶魔跟班2008-07-28 18:13
using 不常用吧,在书上都没见到过使用的例子,只在声明命名空间是见过。
#10
jstzcl0072008-07-28 18:22
楼主能不能讲讲事务,这在网络编程中要用到的,但是通过bindingsource控件、tableadapter控件自动完成数据库的操作,怎样用事务控制提交、回滚,有人说不好这样用,只能像楼主那样在编写代码的情况下才能用事务,是这样的吗,也太麻烦了
#11
语虫2008-07-28 18:28
讲究礼仪!
#12
xyq7018302008-07-30 22:34
说的非常好。 还有using 最好要多用.因为他会释放资源.
#13
andey2008-07-31 09:05
刚看到...过来顶一下...
嗯...这些东东对Beginer还是不错的呢...
期待更多
#14
eric_wjh2008-07-31 09:53
很好很强大
先谢谢版主了
#15
师妃暄2008-08-02 13:44
[bo][un]andey[/un] 在 2008-7-31 09:05 的发言:[/bo]

刚看到...过来顶一下...
嗯...这些东东对Beginer还是不错的呢...
期待更多

Beginer....总结?
#16
klose19862008-08-02 20:40
连接数据库时有的会有
DbProviderFactory dbProviderFactory = DbProviderFactories.GetFactory("System.Data.SqlClient");
DbConnection dbConn = dbProviderFactory.CreateConnection();
DbCommand dbComm=dbProviderFactory.CreateCommand();
DbProviderFactory 到底是什么,有什么用处,什么时候用呢?
#17
朗朗2008-08-03 08:38
[bo][un]redcar[/un] 在 2008-7-28 17:25 的发言:[/bo]

using就是使用,顾名思义了.
比如,你要使用MM,就这样写
using mm;
然后mm下面的所有功能就可以直接调用了.否则,你必须这样
mm.kiss;
mm.ml;
using了之后就可以这样
kiss;
ml;

还有1种用法就是
using(mm)
 ...



这个比喻好...
#18
小仙2008-08-19 21:28
呃。。学习拉,ERP是啥东东。。。
#19
jy024022312008-08-20 09:00
我是新手,讲了这个对我很有用,因为准备要做项目了,正在练习中。。。
#20
dream6982008-08-20 09:42
楼主 很强大啊~  但是感觉应该说点基础的吧~
毕竟新人很多,LZ 意下如何啊?
#21
雪雨星风2008-08-20 10:05
看看
#22
师妃暄2008-08-21 18:32
[bo][un]dream698[/un] 在 2008-8-20 09:42 的发言:[/bo]

楼主 很强大啊~  但是感觉应该说点基础的吧~
毕竟新人很多,LZ 意下如何啊?

这还不够基础啊?
#23
bingling7372008-08-22 11:07
基础
已经是蛮基础的了,呵呵,有福系了一遍,
感觉很好!不错
#24
chongyusheng2008-08-22 11:28
我用的是。net2008 他自己带是数据库是server 2005   在建立连接时总是提示错误请各位高手指点~~
#25
我爱一条柴2008-08-30 14:25
感谢老师的悉心讲解
#26
okdo2008-09-05 11:47
[bo][un]redcar[/un] 在 2008-7-28 17:25 的发言:[/bo]

using就是使用,顾名思义了.
比如,你要使用MM,就这样写
using mm;
然后mm下面的所有功能就可以直接调用了.否则,你必须这样
mm.kiss;
mm.ml;
using了之后就可以这样
kiss;
ml;

还有1种用法就是
using(mm)
 ...

强悍~ 通俗易懂。。。。
#27
slny2008-09-08 15:30
太好了,谢谢楼主!不过有点疑问,最后一段代码中
SqlDataAdapter adapter = new SqlDataAdapter(sql, conn);
括号里的sql是不是应该用sqlstr的呢。我是刚开始学C#,谢谢指教!
#28
eric_wjh2008-09-09 11:06
版主
我最近在看ADO。NET
但是有点不明白和麻烦事
就是在用对象oleDb时
不能把dataset的数据更新到现有的Access数据库中
不知道版主能否写个用对象可视化操作的例子啊
就是用oleDbConnection,oleDbAdapter,dataset对象的
不用写什么连接代码的啊
直接设置属性的啊
#29
myemail19832008-09-22 13:43
师师,问你下你的帖子中的一个问题
行SQL语句的对象.注意两个参数
= CommandType.Text;     
我平时执行时不加这个语句也没事,请问,如果我都是SQL语句,没有存储过程,是不是可以不加了?
见公司里的这句话也有,但就是不知道为什么要加着
#30
geriser2008-09-22 21:37
using用法看一下博客园anytao,他讲的不错
#31
zery2008-09-22 22:29
[bo][un]redcar[/un] 在 2008-7-28 17:25 的发言:[/bo]

using就是使用,顾名思义了.
比如,你要使用MM,就这样写
using mm;
然后mm下面的所有功能就可以直接调用了.否则,你必须这样
mm.kiss;
mm.ml;
using了之后就可以这样
kiss;
ml;

还有1种用法就是
using(mm)
 ...

比喻不错,哈哈!
#32
师妃暄2008-09-22 22:34
回复 28# eric_wjh 的帖子
建议把你遇到的错误贴上来好解决
#33
师妃暄2008-09-22 22:35
[bo][un]myemail1983[/un] 在 2008-9-22 13:43 的发言:[/bo]

师师,问你下你的帖子中的一个问题
行SQL语句的对象.注意两个参数
= CommandType.Text;     
我平时执行时不加这个语句也没事,请问,如果我都是SQL语句,没有存储过程,是不是可以不加了?
 ...


默认是SQL语句..如果是存储过程就一定要写了
#34
myemail19832008-09-22 23:42
原来回过了,呵呵
#35
keytolove2008-09-23 10:02
每次做这些都觉得很散,现在好了`谢谢楼主!`
#36
dedebbs2008-09-23 19:11
请教!
楼主,我想问C#做3D的图形好做吗?有没有推荐来学习的资料或者书籍?急需。谢了!
#37
mao4mao2008-09-23 20:32
是个好帖子~
   赞一个哦~
#38
2008-09-23 22:41
虽然我还刚学什么都看不懂 但我觉得楼主真的很强悍 不知道我什么时候能达到这种境界
#39
notrain2008-10-10 17:01
楼主,问个问题
在很多地方,貌似MSDN上也是
有这么一句话
尽晚的创建打开连接,尽早的释放连接资源,不要寄希望与系统的资源回收机制
那用using这样的方式资源是否一定可以在恰当的时候被释放?
#40
wuyinghui88082008-10-10 19:40
楼主写的有太过于复杂了吧
简单话说
首先引引用命名空间

using System.Data.SqlClient;
using WindowsApplication1.Properties;//具体查看帮助setting()具体属性


代码如下

private SqlConnection coon;
        private DataSet ds;
        private SqlDataAdapter sda;

        private void Frm1_Load(object sender, EventArgs e)
        {
            coon = new SqlConnection(new Settings().Setting);
            ds = new DataSet();
            sda = new SqlDataAdapter("select * from 表名", coon);
            sda.MissingSchemaAction = MissingSchemaAction.AddWithKey;
            sda.Fill(ds);
            bs.DataSource = ds.Tables[0];
            dataGridView1.DataSource = bs;
        }

若是做简单查询,建议用绑定来做,会比较简单
#41
righgrea2008-10-10 23:05
我是新手,还是赞一个!谢谢楼主!
#42
skyzoneskyzone2008-10-11 16:11
string connstr = ConfigurationManager.ConnectionStrings["MaSqlConnection"].ConnectionString;
就可以了。注意引用命名空间using System.Configuration(项目要添加相关引用,网站中不需要)
========================================================================================
这段里ConfigurationManager貌似没有找到可以调用的。(我已经添加了引用了)
#43
小仙2008-10-11 18:35
嗯,不客气,不客气。
#44
styleyang2008-10-15 15:56
using就是使用,顾名思义了.
比如,你要使用MM,就这样写
using mm;
然后mm下面的所有功能就可以直接调用了.否则,你必须这样
mm.kiss;
mm.ml;
using了之后就可以这样
kiss;
ml;

还有1种用法就是
using(mm)
...



这个比喻太贴切了````这位兄弟太有才
#45
liumu_2012008-10-16 11:14
确实,讲的比书上强多了,书上的太单调,太模糊了,初学者根本就一头雾水,强烈要求楼主再接再厉,每个知识点都讲上一遍,为我们指点迷津
#46
liumu_2012008-10-16 11:15
确实,讲的比书上强多了,书上的太单调,太模糊了,初学者根本就一头雾水,强烈要求楼主再接再厉,每个知识点都讲上一遍,为我们指点迷津
#47
小仙2008-10-16 14:17
[bo][un]liumu_201[/un] 在 2008-10-16 11:15 的发言:[/bo]

确实,讲的比书上强多了,书上的太单调,太模糊了,初学者根本就一头雾水,强烈要求楼主再接再厉,每个知识点都讲上一遍,为我们指点迷津

这个主意不错~
#48
lubi2008-10-17 00:26
必定要依靠与数据库进行交互
这一句是不对的,因为Oracle自己开发一套数据库连接的数据库控件()基本用法是一样的,多了一点特别的功能,我也没用过那些特别功能。



中国最先进的MES:PRINCE-MES HTTP://WWW.
dotnet 技术学习群:32524881,MES讲座群6425583
http://shop36404540.
#49
ilovetea2008-10-29 19:27
7楼兄弟强,向你学习

using就是使用,顾名思义了.
比如,你要使用MM,就这样写
using mm;
然后mm下面的所有功能就可以直接调用了.否则,你必须这样
mm.kiss;
mm.ml;
using了之后就可以这样
kiss;
ml;

还有1种用法就是
using(mm)
{xxoo}
这个的好处就是会自动释放资源,不要手动指定
mm.dispose;
#50
爱忧伤2008-10-29 20:20
= CommandType.Text;这个确实每次不加都没事的。那问下在什么情况加这个呢?
恩,今天学了using的用法了,顶了!
#51
itati2008-10-30 09:25
支持楼主,希望以后还能有好东东啊!
12