第七周学习笔记(ADO.Net中DataTable的应用)

(一)知识点描述

       ADO.NET可以在与数据库断开连接的方式下通过DataSet或DataTable对象进行数据处理,当需要更新数据时才重新与数据源进行连接,并更新数据源。DataTable对象表示保存在本机内存中的表,它提供了对表中行列数据对象的各种操作。

      可以直接将数据从数据库填充到DataTable对象中,也可以将DataTable对象添加到现有的DataSet对象中。在断开连接的方式下,DataSet对象提供了和关系数据库一样的关系数据模型,代码中可以直接访问DataSet对象中的DataTable对象,也可以添加、删除ADO.NET对象DataTable。ADO.NET对象SqlDataAdapter通过SelectCommand、InsertCommand、UpdateCommand和DeleteCommand属性为后台数据库提供对应的操作命令,并传递需要的参数。一般情况下,只需要提供SELECT语句和连接字符串创SqlDataAdapter对象,然后利用SqlCommandBuilder对象生成InsertCommand、UpdateCommand和 DeleteCommand属性。

各种具体操作如下:

一、创建DataTable对象

可以通过以下两种方式创建DataTable对象:

(1)通过DataTable类的构造函数创建DataTable对象,例如:

DataTable table = new DataTable();

(2)调用DataSet的Tables对象的Add方法创建DataTable对象

DataSet dataset = new dataSet( );

DataTable table = dataset.Tables.Add(“Table1”);

二、填充DataTable对象

以连接SQL Sever类型数据库为例:

①声明并实例化SQL命令(SqlCommand)、SQL数据适配器(SqlDataAdapter);

②将SQL命令的连接属性指向SQL连接;

③将SQL数据适配器的查询命令属性指向SQL命令;

④打开SQL连接,SQL数据适配器读取数据,并填充数据表;

DataSet dataset = new DataSet();  

DataTable table = dataset.Tables.Add("Table1");

二、填充DataTable对象

以连接SQL Sever类型数据库为例:

①声明并实例化SQL命令(SqlCommand)、SQL数据适配器(SqlDataAdapter);

②将SQL命令的连接属性指向SQL连接;

③将SQL数据适配器的查询命令属性指向SQL命令;

④打开SQL连接,SQL数据适配器读取数据,并填充数据表;

SqlCommand sqlCommand = new SqlCommand();

sqlCommand.Connection = sqlConnection;

SqlDataAdapter sqlDataAdapter = new SqlDataAdapter();

sqlCommand.CommandText ="SELECT * FROM tb_list ;";

sqlDataAdapter.SelectCommand = sqlCommand;

sqlConnection.Open();  

sqlDataAdapter.Fill(this.Table1);

sqlConnection.Close(); 

填充好的数据表,可以作为数据网格视图对象(DataGridView)的数据源,在网格视图中显示数据表内容

this.dataGridView1.DataSource = Table1;

三、在DataTable中创建行

①为原数据表创建新的行

给原数据表新建一个数据行(使用方法NewRow),该行的状态为附加。

DataRow  Row1 = this.Table1.NewRow();                               

②为新创建的行赋值

(1)可以直接为新建数据行赋值

Row1["Name"] = “张三”;

Row1["No"] = 001;

(2)可以绑定已有数据网格视图中的数据行,转换其类型为数据行视图类型(DataRowView),并获取数据行

DataRow  Row1 =((DataRowView)this.dataGridView1.CurrentRow.DataBoundItem).Row

使用这种方法新创建的数据行,需要逐一将从原数据网格视图获取的数据行的各列值,赋予已新创建数据行的相应列;

Row2["No"] = Row1["No"];

Row2["Name"] = Row1["Name"];

Row2["Credit"] = Row1["Credit"];

③将添加行至原数据表

利用Add方法将新创建的DataRow对象加入原数据表;随后该行的状态为添加

this.Table1.Rows.Add(Row1);

四、在DataTable中删除行

①删除行

当前数据行删除;随后该行的状态为删除

Row1.Delete();

②撤销“行的删除”

(1)声明已删课程数据行(即先前从原数据表中删除的数据行);

已删课程数据行可通过课程数据表的方法Select查得,该方法接受查询条件、排序条件、行状态条件等参数,并返回数据行数组;

(2)已删课程数据行拒绝更改,即回滚先前对其执行的删除;随后该行的状态为未更改;

DataRow Row1 =  this.Table1.Select("No='123'", "",DataViewRowState.Deleted)[0];

Row1.RejectChanges();

③行的移除

从数据表的行集合中移除当前数据行,随后该行的状态为附加;

this.Table1.Rows.Remove(Row1);

五、设置DataTable对象的主键

关系数据库中的表一般都有一个主键,用来惟一标识表中的每一行记录。通过DataTable对象的PrimaryKey属性可以设置Datatable的主键。主键可以是一个或者多个DataColumn对象组成的数组。例如:

DataColumn[] key = new DataColumn[1];//dt是一个DataTable对象   

key[0] = dt.Columns[0];  

dt.PrimaryKey = key;

六、DataTable更新数据库

此处省略了SQL命令(SqlCommand)以及SQL连接(SqlConnection)的声明和实例化

①更新DataTable

声明数据表,并指向更改后的数据网格视图的数据源

(数据源默认类型为object,还需强制转换类型)。

  DataTable Table2 = (DataTable)this.dataGridView1.DataSource;

②绑定DataTable中的列名

向SQL命令的参数集合添加参数的名称、SQL Server数据类型、长度(仅用于定长类型)、所绑定的DataTable的列名;

sqlCommand.Parameters.Add("@Name",SqlDbType.VarChar,0,"Name");                                 

sqlCommand.Parameters.Add("@Gender", SqlDbType.Bit, 0, "Gender");

③更新数据库

(1)声明并实例化SQL数据适配器,同时借助构造函数,将其SelectCommand属性设为先前创建的SQL命令

SqlDataAdapter sqlDataAdapter = new SqlDataAdapter();

sqlDataAdapter.UpdateCommand = sqlCommand;

(2)打开SQL连接;SQL数据适配器根据学生数据表提交更新,并返回受影响行数

sqlConnection.Open();

int rowAffected = sqlDataAdapter.Update(Table2);

sqlConnection.Close();     

六、DataTable的查询

①Select查询

(1)声明并实例化查询返回的行数据(DataRow)集合

(2)利用数据表的自有方法Select进行查询(该方法的效率最低).

DataRow[] Rows1 =this.Table1.Select("Pinyin LIKE '%" + this.textBox0.Text.Trim() + "%'");

②Find查询

Find:数据表的行集合的方法Find,根据主键值快速查找,并返回其所在的数据行;

DataRow Row5 = this.Table1.Rows.Find(this.textBox0.Text.Trim());

③FindRows查询

FindRows: 数据视图的方法FindRows,根据排序列快速查找,并返回数据行视图数组

DataRowView[] DataRowViews1 = this.Table1.FindRows(this.textBox1.Text.Trim());

④将查询结果写入数据表

(1)将查询所得数据行导入(ImportRow方法)至指定数据表中

可将数据网格视图的数据源设为搜索结果数据表,用以显示结果

Table1.ImportRow(Row5);

this.dataGridView1.DataSource = Table1;

(2)对于查询结果为多条数据,即数据行视图数组、行数据(DataRow)集合等

foreach:遍历搜索结果所在数据行视图数组

foreach (DataRowView dataRowView1 in DataRowViews1)

{

Table1.ImportRow(dataRowView1.Row);

}

若存储结果的为行数据(DataRow)集合,同理:

 foreach (DataRow row in Rows1)

{

searchResultTable.ImportRow(row);

}

七、DataTable的克隆与复制

Clone 方法:克隆 DataTable 的结构,包括所有 DataTable 架构和约束

DataTable Table1 = this.Table2.Clone();

Copy 方法:复制该 DataTable 的结构和数据

DataTable Table1 = this.Table2.Copy();

(二)思维导图如下

(三)代码示例及运行截图

using System;

using System.Data;

using System.Configuration;

using System.Data.SqlClient;                                                                                //包含访问SQL Server所需的各类对象;

using System.Drawing;

using System.Windows.Forms;

 

namespace 住院医生工作站

{

 

    public partial class Form1 : Form

    {

 

        /// <summary>

      

        /// </summary>

        private DataTable MedicineTable;

 

        /// <summary>

 

       

      

        /// </summary>

        private DataView MedicineViewByName;

 

        /// <summary>

        /// 公有方法:构造函数;

        /// </summary>

        public Form1()

        {

            InitializeComponent();

            this.StartPosition = FormStartPosition.CenterScreen;                                            //本窗体启动位置设为屏幕中央;

            this.dgv_Medicine.AllowUserToAddRows = false;                                                     //数据网格视图不允许用户添加行;

            this.dgv_Medicine.RowHeadersVisible = false;                                                      //数据网格视图的行标题不可见;

            this.dgv_Medicine.BackgroundColor = Color.White;                                                  //数据网格视图的背景色设为白色;

            this.dgv_Medicine.AutoSizeColumnsMode =

                DataGridViewAutoSizeColumnsMode.AllCells;                                                   //数据网格视图的自动调整列宽模式设为显示所有单元格;

        }

 

        /// <summary>

        /// 私有方法:点击载入按钮;

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void btn_Load_Click(object sender, EventArgs e)

        {

            SqlConnection sqlConnection = new SqlConnection();

            sqlConnection.ConnectionString =

              ConfigurationManager.ConnectionStrings["Sql"].ConnectionString;                             //在字符串变量中,描述连接字符串所需的服务器地址、数据库名称、集成安全性(即是否使用Windows验证);

            SqlCommand sqlCommand = new SqlCommand();                                                       //声明并实例化SQL命令;

            sqlCommand.Connection = sqlConnection;                                                          //将SQL命令的连接属性指向SQL连接;

            sqlCommand.CommandText = "SELECT * FROM tb_Medicine;";                                            //指定SQL命令的命令文本;该命令查询所有课程,以用作数据网格视图数据源;

            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter();                                           //声明并实例化SQL数据适配器;

            sqlDataAdapter.SelectCommand = sqlCommand;                                                      //将SQL数据适配器的查询命令属性指向SQL命令;

            sqlDataAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;                            //设置SQL数据适配器在缺少架构时的动作为追加主键,从而获取数据库中定义的主键,否则无法根据编号搜索课程;

            this.MedicineTable = new DataTable();                                                             //实例化本窗体的课程数据表,用于保存所有课程,以用作数据网格视图数据源;

            sqlConnection.Open();                                                                           //打开SQL连接;

            sqlDataAdapter.Fill(this.MedicineTable);                                                          //SQL数据适配器读取数据,并填充课程数据表;

            sqlConnection.Close();                                                                                                                         //借助本窗体的课程数据表的方法Copy来复制数据表,并赋予本窗体的先修课程数据表,用作先修课程下拉框的数据源;

            this.MedicineViewByName = new DataView();

            this.MedicineViewByName.Table = this.MedicineTable;                                                 //设置课程数据视图对应的数据表;

            this.MedicineViewByName.Sort = "MedicineName ASC";                                                        //设置课程数据视图的排序条件,即查询所覆盖的列;

            this.dgv_Medicine.Columns.Clear();                                                                //数据网格视图的列集合清空;

            this.dgv_Medicine.DataSource = this.MedicineTable;                                                  //将数据网格视图的数据源设为学生数据表;

            this.dgv_Medicine.Columns["No"].HeaderText = "编号";                                              //将数据网格视图的指定列的表头文本设为中文;

            this.dgv_Medicine.Columns["MedicineName"].HeaderText = "药品名称";

            this.dgv_Medicine.Columns["MedicinePrice"].HeaderText = "药品价格";

            this.dgv_Medicine.Columns["Solution"].HeaderText = "使用方法";

            this.dgv_Medicine.Columns["Speed"].HeaderText = "用药间隔";

            this.dgv_Medicine.Columns["Pinyin"].Visible = false;                                              //将数据网格视图的指定列设为不可见;

                

        }

 

 

 

        private void btn_SearchByNo_Click_1(object sender, EventArgs e)

        {

            DataRow searchResultRow = this.MedicineTable.Rows.Find(this.txb_MedicineNo.Text.Trim());            //借助本窗体的课程数据表的行集合的方法Find,根据主键值(即课程编号)快速查找相应课程,并返回其所在的数据行;但数据行不能作为数据源,需另行创建数据表,并导入该数据行,最后将数据表作为数据源;

            DataTable searchResultTable = this.MedicineTable.Clone();                                         //借助本窗体的课程数据表的方法Clone,创建相同架构的空表,用于保存搜索结果所在数据行;

            searchResultTable.ImportRow(searchResultRow);                                                   //将(复制后的)数据行导入数据表;

            this.dgv_Medicine.DataSource = searchResultTable;     

        }

 

        private void btn_SearchByName_Click_1(object sender, EventArgs e)

        {

            DataRowView[] searchResultRowViews =

               this.MedicineViewByName.FindRows(this.txb_MedicineName.Text.Trim());                            //借助本窗体的按名称排序的课程数据视图的方法FindRows,根据排序列(即课程名称)快速查找相应课程;由于该列并非主键,可能返回多行查询结果,故返回数据行视图数组;数据行视图数组不能直接作为数据源,需转为列表后方可作为数据源;

            DataTable searchResultTable = this.MedicineTable.Clone();                                         //借助本窗体的课程数据表的方法Clone,创建相同架构的空表,用于保存搜索结果所在数据行;

            foreach (DataRowView dataRowView in searchResultRowViews)                                       //遍历搜索结果所在数据行视图数组;

            {

                searchResultTable.ImportRow(dataRowView.Row);                                               //通过每条数据行视图的属性Row获取相应的数据行,并导入数据表;

            }

            this.dgv_Medicine.DataSource = searchResultTable;  

        }

 

        private void txb_Pinyin_TextChanged_1(object sender, EventArgs e)

        {

            DataRow[] searchResultRows =

                this.MedicineTable.Select("Pinyin LIKE '%" + this.txb_Pinyin.Text.Trim() + "%'");             //借助本窗体的课程数据表的方法Select,并提供与SQL类似的谓词表达式作为查询条件,根据拼音缩写进行模糊查询(仅支持%通配符);查询将返回数据行数组;

            DataTable searchResultTable = this.MedicineTable.Clone();                                         //借助本窗体的课程数据表的方法Clone,创建相同架构的空表,用于保存搜索结果所在数据行;

            foreach (DataRow row in searchResultRows)                                                       //遍历搜索结果所在数据行数组;

            {

                searchResultTable.ImportRow(row);                                                           //数据行导入数据表;

            }

            this.dgv_Medicine.DataSource = searchResultTable;  

        }

    }

}

运行效果如图所示:

  1. 载入药品excel表

2.根据编号搜索药品

3.根据名称搜索药品

4.根据拼音缩写搜索药品

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值