第八周学习笔记
一、实现数据表的查找功能
C#界面设置载入、根据工号搜索、根据姓名搜索、根据拼音缩写搜索四个按钮。载入按钮作用是载入医生信息表的信息。
C#主要代码如下:
public partial class frm_Doctor : Form
{
private DataTable doctorTable;
private DataView doctorViewByName;
public frm_Doctor()
{
InitializeComponent();
this.StartPosition = FormStartPosition.CenterScreen;
this.dgv_Doctor.AllowUserToAddRows = false; //数据网格视图不允许用户添加行
this.dgv_Doctor.RowHeadersVisible = false; //数据网格视图不允许用户添加行
this.dgv_Doctor.BackgroundColor = Color.White;//数据网格视图的背景色设为白色
this.dgv_Doctor.AutoSizeColumnsMode =
DataGridViewAutoSizeColumnsMode.AllCells; //数据网格视图的自动调整列宽模式设为显示所有单元格
}
private void btn_Load_Click(object sender, EventArgs e)
{
SqlConnection sqlConnection = new SqlConnection();
sqlConnection.ConnectionString =
"Server=(local);Database=HISDatabase;uid=sa;pwd=2wsx@WSX";
SqlCommand sqlCommand = new SqlCommand();
sqlCommand.Connection = sqlConnection;
sqlCommand.CommandText = "SELECT * FROM tb_doctor;";
//指定SQL命令的命令文本;该命令查询所有医生信息,以用作数据网格视图数据源
SqlDataAdapter sqlDataAdapter = new SqlDataAdapter();
sqlDataAdapter.SelectCommand = sqlCommand;
sqlDataAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
//设置SQL数据适配器在缺少架构时的动作为追加主键,从而获取数据库中定义的主键
this.doctorTable = new DataTable();
//实例化本窗体的医生数据表,用于保存所有医生信息,以用作数据网格视图数据源
sqlConnection.Open();
sqlDataAdapter.Fill(this.doctorTable); //SQL数据适配器读取数据,并填充医生数据表
sqlConnection.Close();
this.doctorViewByName = new DataView();
//实例化本窗体的医生数据视图,用于按照名称进行快速查询
this.doctorViewByName.Table = this.doctorTable;//设置医生数据视图对应的数据表
this.doctorViewByName.Sort = "name ASC";//设置课程数据视图对应的数据表
this.dgv_Doctor.Columns.Clear();//数据网格视图的列集合清空
this.dgv_Doctor.DataSource = this.doctorTable;//将数据网格视图的数据源设为医生数据表
this.dgv_Doctor.Columns["no"].HeaderText = "工号";//设置医生数据视图的排序条件,即查询所覆盖的列this.dgv_Doctor.Columns["name"].HeaderText = "姓名";
this.dgv_Doctor.Columns["post"].HeaderText = "职称";
this.dgv_Doctor.Columns["department"].HeaderText = "科室";
this.dgv_Doctor.Columns["Pinyin"].Visible = false;
//数据网格视图的最后一列的自动调整列宽模式设为填充(至数据网格视图右侧边缘)
this.dgv_Doctor.Columns[this.dgv_Doctor.Columns.Count - 1].AutoSizeMode =
DataGridViewAutoSizeColumnMode.Fill;
}
private void btn_SearchByNo_Click(object sender, EventArgs e)
{
DataRow searchResultRow = this.doctorTable.Rows.Find(this.txb_DoctorNo.Text.Trim());
DataTable searchResultTable = this.doctorTable.Clone();
searchResultTable.ImportRow(searchResultRow);
this.dgv_Doctor.DataSource = searchResultTable;
}
private void btn_SearchByName_Click(object sender, EventArgs e)
{
DataRowView[] searchResultRowViews =
this.doctorViewByName.FindRows(this.txb_DoctorName.Text.Trim());
DataTable searchResultTable = this.doctorTable.Clone();
foreach (DataRowView dataRowView1 in searchResultRowViews)
{
searchResultTable.ImportRow(dataRowView1.Row);
}
this.dgv_Doctor.DataSource = searchResultTable;
}
private void txb_Pinyin_TextChanged(object sender, EventArgs e)
{
DataRow[] searchResultRows =
this.doctorTable.Select("Pinyin LIKE ‘%" + this.txb_Pinyin.Text.Trim() + "%‘");
//借助本窗体的课程数据表的方法Select,并提供与SQL类似的谓词表达式作为查询条件,根据拼音缩写进行模糊查询(仅支持%通配符);查询将返回数据行数组
DataTable searchResultTable = this.doctorTable.Clone();
foreach (DataRow row in searchResultRows)
{
searchResultTable.ImportRow(row);
}
this.dgv_Doctor.DataSource = searchResultTable;
}
}
运行结果如下:
载入:
根据工号搜索:
根据姓名搜索:
根据拼音缩写搜索:
二、数据行的应用
以下事例实现选药的功能,先载入数据库端的药品表内容,从左边药品数据表选中药品所在行,点击“>>”即可添加到右边已选药品数据表中。点击“<<”即可取消药品的选中。窗体下端将会显示所选药品的总价格,点击提交及更新数据库端病人表的信息。
C#主要代码如下,比较难懂的已经在代码旁添加了注释。
using System.Data.SqlClient;
namespace _5._4数据表_数据行
{
public partial class frm_MedicineSelection : Form
{
private DataTable MedicineTable;
private DataTable SelectedMedicineTable;
public frm_MedicineSelection()
{
InitializeComponent();
this.StartPosition = FormStartPosition.CenterScreen;
this.dgv_Medicine.ReadOnly = true;
this.dgv_Medicine.AllowUserToAddRows = false;
this.dgv_Medicine.RowHeadersVisible = false;
this.dgv_Medicine.BackgroundColor = Color.White;
this.dgv_Medicine.AutoSizeColumnsMode =
DataGridViewAutoSizeColumnsMode.AllCells;
this.dgv_SelectedMedicine.ReadOnly = true;
this.dgv_SelectedMedicine.AllowUserToAddRows = false;
this.dgv_SelectedMedicine.RowHeadersVisible = false;
this.dgv_SelectedMedicine.BackgroundColor = Color.White;
this.dgv_SelectedMedicine.AutoSizeColumnsMode =
DataGridViewAutoSizeColumnsMode.AllCells;
}
private void btn_Load_Click(object sender, EventArgs e)
{
SqlConnection sqlConnection = new SqlConnection();
sqlConnection.ConnectionString =
"Server=(local);Database=HISDatabase;uid=sa;pwd=2wsx@WSX";
SqlCommand sqlCommand = new SqlCommand();
sqlCommand.Connection = sqlConnection;
sqlCommand.CommandText =
"SELECT No,Name,Cost FROM tb_Medicine WHERE No NOT IN"
+ "(SELECT MedicineNo FROM tb_MedicineSelection WHERE PatientNo=@PatientNo);";
sqlCommand.Parameters.AddWithValue("@PatientNo", "3120707001");
SqlDataAdapter sqlDataAdapter = new SqlDataAdapter();
sqlDataAdapter.SelectCommand = sqlCommand;
this.MedicineTable = new DataTable();
this.SelectedMedicineTable = new DataTable();
sqlConnection.Open();
sqlDataAdapter.Fill(this.MedicineTable);
sqlCommand.CommandText =
"SELECT M.No,M.Name,M.Cost"
+ " FROM tb_Medicine AS M JOIN tb_MedicineSelection AS MS ON M.No=MS.MedicineNo"
+ " WHERE PatientNo=@PatientNo;";
sqlDataAdapter.Fill(this.SelectedMedicineTable);
sqlConnection.Close();
this.dgv_Medicine.Columns.Clear(); //药品数据网格视图的列集合清空;
this.dgv_Medicine.DataSource = this.MedicineTable; //将数据网格视图的数据源设为药品数据表;
this.dgv_Medicine.Columns["No"].HeaderText = "编号"; //将数据网格视图的指定列的表头文本设为中文;
this.dgv_Medicine.Columns["Name"].HeaderText = "名称";
this.dgv_Medicine.Columns["Cost"].HeaderText = "价格";
this.dgv_Medicine.Columns[this.dgv_Medicine.Columns.Count - 1].AutoSizeMode = //数据网格视图的最后一列的自动调整列宽模式设为填充(至数据网格视图右侧边缘);
DataGridViewAutoSizeColumnMode.Fill;
this.dgv_SelectedMedicine.Columns.Clear(); //药品数据网格视图的列集合清空;
this.dgv_SelectedMedicine.DataSource = this.SelectedMedicineTable; //将数据网格视图的数据源设为药品数据表;
this.dgv_SelectedMedicine.Columns["No"].HeaderText = "编号"; //将数据网格视图的指定列的表头文本设为中文;
this.dgv_SelectedMedicine.Columns["Name"].HeaderText = "名称";
this.dgv_SelectedMedicine.Columns["Cost"].HeaderText = "价格";
this.dgv_SelectedMedicine.Columns[this.dgv_SelectedMedicine.Columns.Count - 1].AutoSizeMode = //数据网格视图的最后一列的自动调整列宽模式设为填充(至数据网格视图右侧边缘);
DataGridViewAutoSizeColumnMode.Fill;
this.lbl_CostSum.Text =
"共" + this.SelectedMedicineTable.Compute("SUM(Cost)", "").ToString() + "元";
}
private void btn_Add_Click(object sender, EventArgs e)
{
if (this.dgv_Medicine.RowCount > 0) //若课程数据网格视图内的行计数大于0;
{
DataRow //声明数据行;
currentMedicineRow = ((DataRowView)this.dgv_Medicine.CurrentRow.DataBoundItem).Row
//当前药品数据行可通过药品数据网格视图的当前行的数据绑定项获得,后者可直接转换为数据行视图,从而获取其相应的数据行;
, selectedMedicineRow = this.SelectedMedicineTable.NewRow();
//已选药品数据行则通过已选药品数据表的方法NewRow来新建;随后该行的状态为附加;
selectedMedicineRow["No"] = currentMedicineRow["No"];
//逐一将当前药品数据行的各列值,赋予已选药品数据行的相应列;
selectedMedicineRow["Name"] = currentMedicineRow["Name"];
selectedMedicineRow["Cost"] = currentMedicineRow["Cost"];
this.SelectedMedicineTable.Rows.Add(selectedMedicineRow);
//已选药品数据行加入已选药品数据表;随后该行的状态为添加;
currentMedicineRow.Delete();
//当前药品数据行删除;随后该行的状态为删除;
this.lbl_CostSum.Text =
//在标签中显示已选药品的总价格;
"共" + this.SelectedMedicineTable.Compute("SUM(Cost)", "").ToString() + "元";
//借助已选药品数据表的方法Compute,实现简单计算,例如聚合;
}
}
private void btn_Remove_Click(object sender, EventArgs e)
{
if (this.dgv_SelectedMedicine.RowCount > 0) //若课程数据网格视图内的行计数大于0;
{
DataRow selectedMedicineRow = //声明已选药品数据行;
((DataRowView)this.dgv_SelectedMedicine.CurrentRow.DataBoundItem).Row;
//当前药品数据行可通过已选药品数据网格视图的当前行的数据绑定项获得,后者可直接转换为数据行视图,从而获取其相应的数据行;
if (selectedMedicineRow.RowState == DataRowState.Unchanged)
//若已选药品数据行的行状态为未更改(即该药品为先前已选、且已提交,则当前不允许退选);
{
return;
//返回;
}
else //否则(即该药品刚从药品数据表中选中、尚未提交,则当前允许退选);
{
string courseNo = selectedMedicineRow["No"].ToString();
//获取当前药品数据行的药品编号;
DataRow deletedMedicineRow =
//声明已删药品数据行(即先前从药品数据表中删除的数据行);
this.MedicineTable.Select("No=‘" + courseNo + "‘", "", DataViewRowState.Deleted)[0]; //已删药品数据行可通过药品数据表的方法Select,该方法接受查询条件、排序条件、行状态条件等参数,并返回数据行数组;
this.SelectedMedicineTable.Rows.Remove(selectedMedicineRow);
//从已选药品数据表的行集合中移除当前药品数据行;随后该行的状态为附加;
deletedMedicineRow.RejectChanges();
//已删药品数据行拒绝更改,即回滚先前对其执行的删除;随后该行的状态为未更改;
this.lbl_CostSum.Text =
//在标签中显示已选药品的总价格;
"共" + this.SelectedMedicineTable.Compute("SUM(Cost)", "").ToString() + "元"; /
/借助已选药品数据表的方法Compute,实现简单计算,例如聚合;
}
}
}
private void btn_Submit_Click(object sender, EventArgs e)
{
SqlConnection sqlConnection = new SqlConnection();
sqlConnection.ConnectionString =
"Server=(local);Database=HISDatabase;uid=sa;pwd=2wsx@WSX";
SqlCommand sqlCommand = new SqlCommand();
sqlCommand.Connection = sqlConnection;
sqlCommand.CommandText =
"INSERT tb_MedicineSelection(PatientNo,MedicineNo)"
+ "VALUES(@PatientNo,@MedicineNo);";
//指定SQL命令的命令文本;该命令插入选药记录;
sqlCommand.Parameters.AddWithValue("@PatientNo", "3120707001"); //向SQL命令的参数集合添加参数的名称、SQL Server数据类型、长度(仅用于定长类型)、所绑定的数据表中的列名;
sqlCommand.Parameters.Add("@MedicineNo", SqlDbType.Char, 8, "No");
SqlDataAdapter sqlDataAdapter = new SqlDataAdapter();
//声明并实例化SQL数据适配器;
sqlDataAdapter.InsertCommand = sqlCommand; //将SQL数据适配器的查询命令属性指向SQL命令;
sqlConnection.Open(); //打开SQL连接;
int rowAffected = sqlDataAdapter.Update(this.SelectedMedicineTable);
//SQL数据适配器根据药品数据表提交更新,并返回受影响行数;
sqlConnection.Close(); //关闭SQL连接;
MessageBox.Show("插入" + rowAffected.ToString() + "行。");
}
}
}
运行如下:
三、数据列的应用
以分页为例,来实现数据列的应用。
载入药品信息,药品信息以八行为单位,逐一显示。单击下一页按钮,就会显示下一页的药品信息,单击上一页显示上一页的信息。
C#实现代码如下:
using System.Data.SqlClient;
namespace _5._5数据表_分页
{
public partial class frm_Medicine : Form
{
private DataTable MedicineTable;
private DataView CurrentPageView;
private int PageSize;
private int CurrentPageNo;
private int MaxPageNo;
public frm_Medicine()
{
InitializeComponent();
this.StartPosition = FormStartPosition.CenterScreen;
this.dgv_Medicine.ReadOnly = true;
this.dgv_Medicine.AllowUserToAddRows = false;
this.dgv_Medicine.RowHeadersVisible = false;
this.dgv_Medicine.BackgroundColor = Color.White;
this.dgv_Medicine.AutoSizeColumnsMode =
DataGridViewAutoSizeColumnsMode.AllCells;
}
private void btn_Load_Click(object sender, EventArgs e)
{
this.PageSize = 8;
this.CurrentPageNo = 1;
SqlConnection sqlConnection = new SqlConnection();
sqlConnection.ConnectionString =
"Server=(local);Database=HISDatabase;uid=sa;pwd=2wsx@WSX";
SqlCommand sqlCommand = new SqlCommand();
sqlCommand.Connection = sqlConnection;
sqlCommand.CommandText =
"SELECT * FROM tb_Medicine";
SqlDataAdapter sqlDataAdapter = new SqlDataAdapter();
sqlDataAdapter.SelectCommand = sqlCommand;
this.MedicineTable = new DataTable();
this.MedicineTable.TableName = "MedicineInformation";
sqlConnection.Open();
sqlDataAdapter.Fill(this.MedicineTable);
DataColumn rowIdColumn = new DataColumn();
rowIdColumn.ColumnName = "RowID";
rowIdColumn.DataType = typeof(int);
rowIdColumn.AutoIncrement = true;
rowIdColumn.AutoIncrementSeed = 1;
rowIdColumn.AutoIncrementStep = 1;
this.MedicineTable.Columns.Add(rowIdColumn);
sqlCommand.CommandText = "SELECT * FROM tb_Medicine";
sqlDataAdapter.Fill(this.MedicineTable);
sqlConnection.Close();
this.MaxPageNo = this.MedicineTable.Rows.Count / this.PageSize + 1;
this.CurrentPageView = new DataView();
this.CurrentPageView.Table = this.MedicineTable;
this.CurrentPageView.Sort = "RowID ASC";
this.CurrentPageView.RowFilter =
"RowID >" + (this.CurrentPageNo - 1) * this.PageSize
+ " AND RowID <=" + this.CurrentPageNo * this.PageSize;
this.dgv_Medicine.Columns.Clear();
this.dgv_Medicine.DataSource = this.CurrentPageView; //将数据网格视图的数据源设为药品数据表;
this.dgv_Medicine.Columns["No"].HeaderText = "编号"; //将数据网格视图的指定列的表头文本设为中文;
this.dgv_Medicine.Columns["Name"].HeaderText = "名称";
this.dgv_Medicine.Columns["Guige"].HeaderText = "规格";
this.dgv_Medicine.Columns["Unit"].HeaderText = "单位";
this.dgv_Medicine.Columns["Cost"].HeaderText = "价格";
this.dgv_Medicine.Columns[this.dgv_Medicine.Columns.Count - 1].AutoSizeMode = //数据网格视图的最后一列的自动调整列宽模式设为填充(至数据网格视图右侧边缘);
DataGridViewAutoSizeColumnMode.Fill;
}
private void btn_PreviosPage_Click(object sender, EventArgs e)
{
if (this.CurrentPageNo > 1)
//若当前页号大于1;
{
this.CurrentPageNo--;
//则当前页号递减;
}
this.CurrentPageView.RowFilter = //设置药品数据视图的行筛选条件,即筛选当前页的记录;
"RowID >" + (this.CurrentPageNo - 1) * this.PageSize
+ " AND RowID <=" + this.CurrentPageNo * this.PageSize;
}
private void btn_NextPage_Click(object sender, EventArgs e)
{
if (this.CurrentPageNo < this.MaxPageNo) //若当前页号尚未超出最大页号;
{
this.CurrentPageNo++; //则当前页号递增;
}
this.CurrentPageView.RowFilter = //设置药品数据视图的行筛选条件,即筛选当前页的记录;
"RowID >" + (this.CurrentPageNo - 1) * this.PageSize
+ " AND RowID <=" + this.CurrentPageNo * this.PageSize;
}
}
}