一、前文回顾

  在本系列第一篇文章中我们介绍了关系型数据库的概念,然后学习了如何使用企业管理器建立数据库表和添加数据,基础的SQL语句:查询,增加,修改,删除的用法,最后用我们讲解的知识实现了一个WINFORM的登陆窗体。

二、概述

  这将是[MrYoung教程:易学之道]ADONET基础系列文章的第二篇,在本篇中我们来关注数据展现问题,如何从数据库中取出数据并展示到我们的程序中,其中将讲述DATASET,SQLDATAADAPER和DATAGRIDVIEW控件。

  本文配套视频 优酷专辑地址:http://www.youku.com/playlist_show/id_6080910.html

                            本集地址:http://v.youku.com/v_playlist/f6080910o1p0.html

三、主要内容

  3.1 USING的使用。

  3.2 DataSet介绍。

  3.3 SqlDataAdapter介绍。

  3.4 控件的数据绑定。

四、USING使用

  4.1 Using(),作为语句,它主要用于定义一个范围,表示在此范围的末尾将释放对象。比如上文中我们在实例化SqlConnection对象,在使用完以后应该显示的调用该对象的CLOSE方法确保关闭对象,现在我们可以使用USING来实例化它,这样当使用完以后系统会帮我们自动释放掉该对象,如:
 
 
//在括号内实例化对象,那么在花括号的代码执行完毕后系统将帮我们释放sqlcon对象 
using (SqlConnection sqlcon = new SqlConnection(connectionString))
{
sqlcon.open();
//DoSomeThing;
}

  4.2 using 语句确保调用 Dispose,即使在调用对象上的方法时发生异常也是如此,其实try..catch也是运用的USING原理,感兴趣的大家可以去详细了解下。

  4.3 强调调用Dispose使用using,强调异常处理使用try..catch

  4.4 在学习了USING以后,我们来讲我们的BaseOperate重写,将所有方法和字段改为静态static,使用static的成员不用实例化即可直接使用,首先声明一个静态字符串connectionString用于保存字符串连接,然后写一个静态方法getStrcon用于获取字符串连接,声明一个静态构造函数,以便在调用本类时确保给connectionString正确赋值,代码如下:

 

 

        /// <summary>
        /// 数据库连接字符串
        /// </summary>
        public static string connectionString =null;

       /// <summary>
       /// 构造函数
       /// </summary>
        static BaseOperate()
        {
            connectionString = getStrcon();
        }
        /// <summary>
        /// 获取数据库连接字符串
        /// </summary>
        /// <returns></returns>
        public static string getStrcon()
        {
            return "packet size=4096;data source=127.0.0.1;persist security info=True;initial catalog=Db_Example;user id=sa";
        }

 

   接着把我们上文的getcom方法也改为静态方法,以便在使用完该方法后系统自动帮我们释放资源和对象:

 

        /// <summary>
        /// 执行SQLCOMMAND命令
        /// </summary>
        /// <param name="str_sql">要执行的SQL语句</param>
        public static void getcom(string str_sql)
        {
            using (SqlConnection sqlcon = new SqlConnection(connectionString))
            {
                using (SqlCommand sqlcom = new SqlCommand(str_sql, sqlcon))
                {

                    sqlcon.Open();
                    sqlcom.ExecuteNonQuery();

                }
            }
        }

 

  而对于getread方法,因为要返回SqlDataReader对象,并且它是这样来实例化的sqlcom.ExecuteReader(CommandBehavior.CloseConnection),所以我们不使用USING,而是由调用者在使用完成后显示的关闭连接,同样我们也改写他为静态方法如下:

 

        /// <summary>
        /// 创建SQLDATAREADER对象
        /// </summary>
        /// <param name="str_sql">要执行的SQL语句</param>
        /// <returns>返回SQLDATAREADER对象</returns>
        public static SqlDataReader getread(string str_sql)
        {
            SqlConnection sqlcon = new SqlConnection(connectionString);
            SqlCommand sqlcom = new SqlCommand(str_sql, sqlcon);
            sqlcon.Open();
            SqlDataReader sqlread = sqlcom.ExecuteReader(CommandBehavior.CloseConnection);
            return sqlread;

        }

五、DATASET

  5.1 DataSet 是 ADO.NET 结构的主要组件,它是从数据源中检索到的数据在内存中的缓存。 我们简单来讲,DATASET就是我们执行数据库查询语句SELECT后返给我们的结果集,他包含了我们查询的结果,并且是储存在内存中的。但DATASET并不仅限于数据库的查询。

  5.2 对于任何数据源,它都提供一致的关系编程模型。在DataSet中既定义了数据表的约束关系以及数据表之间的关系,还可以对数据表中的数据进行排序等。

  5.3 独立性,既可以以离线方式,也可以以实时连接来操作数据库中的数据。

   如上图所示,一个DATASET可以包含多个DATATABLE数据表,而一个数据表相当于我们数据库中的表,如TB_USERINFO,他具有行和列,当我们执行数据库查询后就会得到一个DATASET,如果我们查询的是TB_USERINFO的信息,那么在DATASET中就会存在一个表,他的序列为0(注意,一般我们都是已0开始计数,而不是1),表示为DATASET.TABLE[0]。在SQL中,我们可以通过SqlDataAdapter类执行查询,得到一个DATASET对象。

六、SqlDataAdapter 

  6.1 表示用于填充 DataSet 和更新 SQL Server 数据库的一组数据命令和一个数据库连接

  6.2 SqlDataAdapter 构造函数 (String, SqlConnection),他接受一个查询SQL的命令和一个数据库连接对象。

  6.3 DbDataAdapter.Fill 方法 (DataSet),通过此方法,我们即可填充传入的DATASET形参从而获取查询结果。

  下面我们来扩展我们的BaseOperate类,增加一个查询方法,返回一个DATASET,如下所示

        /// <summary>
        /// 执行查询语句,返回DataSet
        /// </summary>
        /// <param name="SQLString">查询语句</param>
        /// <returns>DataSet</returns>
        public static DataSet getds(string str_sql)
        {
            //使用USING
            using (SqlConnection sqlcon = new SqlConnection(connectionString))
            {
                //实例化一个DATASET对象
                DataSet ds = new DataSet();
                sqlcon.Open();
                //实例化一个SqlDataAdapter对象
                SqlDataAdapter sqldata = new SqlDataAdapter(str_sql, sqlcon);
                //填充ds
                sqldata.Fill(ds);
                return ds;
            }
        }

  

七、COMBOBOX的数据绑定

  在我们前文的登录界面中,我们的用户名需要用户手动的输入,在这里我们学习了DATASET后把他改为COMBOBOX下拉框(删除原来的txtUsername控件,重新拖入一个COMBOBOX控件,并取名为cmbUserName),然后在打开程序的时候自动吧TB_USER表中的USERNAME这列绑定到COMBOBOX当中。

 

  在这里主要用到了一个COMBOBOX的DATASOURCE属性,他用来获取或设置包含用于填充该控件中的项的值列表的源。那么我们首先调用getds方法查询tb_user表所有记录,得到一个DATASET对象,SQLDATAADAPTER的FILL方法会把查询结果放到DATASET中的DATATABLE中,每次填充DATASET都会放到一个DATATABLE中,这些DATATABLE是以0,1,2,3,4.。。这样排列的,所以我们把得到的DATATABLE赋给COMBOBOX的DATASOURCE属性,然后调用COMBOBOX的DisplayMember用于设置显示的是DATATABLE中的那一列的值。在登录窗体的加载中编写如下代码:

        private void frmLogin_Load(object sender, EventArgs e)
        {
            //实例化一个DATASET
            DataSet ds = new DataSet();
            //通过getds方法执行查询所有的记录然后赋给ds
            ds = BaseClass.BaseOperate.getds("select * from tb_user");
            //把ds的Tables[0]作为数据源绑定给cmbUserName
            cmbUserName.DataSource = ds.Tables[0];
            //最后设置显示的列为username用户名
            cmbUserName.DisplayMember = "username";
        }

  重新运行后我们的cmbUserName下拉框已经可以正确显示我们的用户名了。

八、DataGridView 控件

    8.1 概述:使用 DataGridView 控件,可以显示和编辑来自多种不同类型的数据源的表格数据。

    8.2 将数据绑定到 DataGridView 控件非常简单和直观,在大多数情况下,只需设置 DataSource 属性即可。

    8.3 我们在frmMain窗体中拖入一个DataGridView 控件,默认名称不变,同时我们在TB_USER表中新增几列,然后用我们上文中讲解的方法添加一些行进去。

  

  接着我们在frmMain当中拖入一些文本框和标签,用于显示这些信息,窗体如下:

 

  首先我们在窗体加载的方法中去查询TB_USER表中的数据把他绑定到我们的DATAGRIDVIEW控件,方法比较类似于COMBOBOX,代码如下:

 

       private void frmMain_Load(object sender, EventArgs e)
        {
            //select 列名 as XX表示别名,允许我们对查询结果列名重新赋值
            ds = BaseClass.BaseOperate.getds("select id as 编号,username as 姓名,userpassword as 密码,userage as 年龄,userphone as 电话,useraddress as 地址 from tb_user");
            //绑定数据到我们的DATAGRIDVIEW控件
            dataGridView1.DataSource = ds.Tables[0];
            //获取登陆时的用户名和密码显示想标签控件上
            label1.Text = "当前用户:" + frmLogin.M_str_name+"|登录时间:"+DateTime.Now.ToString();          
        }

  8.4 接下来我们来实现这样一个功能,当用户点击DATAGRIDVIEW中的一行时我们把数据显示在上面不同的文本框中。首先,我们需要知道DATAGRIDVIEW有这样一个事件叫做DataGridView.CellClick事件,它在单元格的任何部分被单击时发生。然后在我们要知道用这样的方法来取控件中的某个数据,Rows[第几行].Cells[第几列].value,要注意的是VALUE是一个OBJECT对象,我们要把他赋给文本框的TEXT时应该把他转换为字符串类型。同样,这里第几行和第几列是整形,并且是从0开始计数的。在点击事件中e.RowIndex代表用户点击的当前行,最后的代码如下:

 

  

       private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            //都是以0开始计数 而不是1
            txtID.Text=Convert.ToString(dataGridView1.Rows[e.RowIndex].Cells[0].Value);
            txtUserName.Text = Convert.ToString(dataGridView1.Rows[e.RowIndex].Cells[1].Value);
            txtPWD.Text = Convert.ToString(dataGridView1.Rows[e.RowIndex].Cells[2].Value);
            txtAge.Text = Convert.ToString(dataGridView1.Rows[e.RowIndex].Cells[3].Value);
            txtPhone.Text = Convert.ToString(dataGridView1.Rows[e.RowIndex].Cells[4].Value);
            txtAddress.Text = Convert.ToString(dataGridView1.Rows[e.RowIndex].Cells[5].Value);
        }

 

    好了,现在F5运行,我们就看到了所有的效果

九、总结

  本文我们以一个数据的展示窗体像大家介绍了SQLDATAADAPTER,知道了DATASET的基本使用,他是我们内存中的缓存数据集合,并介绍了如何绑定数据到我们的窗体控件和如何获取DATAGRIDVIEW当中的指定单元格的值。

十、下集预告

  再下一集中我们将讲解如何使用ADO,NET增修删还有查询数据,并进一步完善我们的FRMMIAN窗体,并引出SQL注入的原理,敬请期待。

十一、其他信息

  本文章内容对应视频教程的第二讲[MrYoung教程:易学之道]2ADONET基础之数据展现,在文首我已经给出了优酷的链接,建议家先观看视频,然后再来看本文会更加清晰,若有不明白的的地方,当然你也可以给我留言或加入QQ群13615607交流,在群里有本文的视频教程,PPT,源码供下载。

  

  帮助QQ群:13615607,请注明来自博客园

  本文配套视频 优酷专辑地址:http://www.youku.com/playlist_show/id_6080910.html

            本集地址:http://v.youku.com/v_playlist/f6080910o1p0.html

十二、本系列已有教程

  11.1 [MrYoung教程:易学之道]1ADONET基础及登录模块的实现 1-1

 

  11.2[MrYoung教程:易学之道]1ADONET基础及登录模块的实现 1-2
   

作者: [MrYoung] 发表于 2011-05-19 20:49 原文链接

推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架