★★案例:书籍管理BMS
界面
基本流程
1. 创建项目BMS
2. 拖控件
Lable(lblKey),
TextBox(
txtKey
)
Lable(lblCate)
ComboBox(
cboCate
)
Button(
btSearch
)
DataGridView(
dgvBooks
)
Lable(lblI),Lable(lblID),Lable,TextBox(
txtTitle
),Lable,CombocBox(
cboCateU
),Lable,Text(
txtAuthor
)
Lable,TextBox(
txtContent
)
Button(btnAdd),Button(btnUpdate),Button(btnDel)
3. 添加SqlHelper.cs类文件
a) 导入System.Configuration引用
b) 添加命名空间System.Configuration;
c) ConfigurationManager.ConnectionStrings[‘’conStr’’].connectionString;
4. 添加配置文件
<ConnectionString>
<addname="conStr"connectionString ="server=.;database=SimpleAriticle;IntegrateSecurity =True;"/>
</ConnectionString>
作用:运行时,从配置文件中把name叫做conStr的这个配置文件的结点所对应的这个值(
server=.;database=
SimpleAriticle;Integrate Security =True;
)给读出来
内容理解
添加Book实体类
:
添加这个类的作用:
把表中的数据转换成书的实体,把总个表变成有意义的对象的集合
(是以Object类型存储的)。
本身就是Category,只是包装成了Object而已,所以可以转化为Category,如果本身就是Object类型,则不能转。
其它:
选项控件里面有两套数据源集合,即有两种存储数据的方式。
反编译:看源码
代码
Books.cs:书籍实体类
namespace BMS { //书籍实体类 class Book { private int bId; private int bCId; privatestring bTitle; private string bContent; private string bAuthor; private bool bIsDel; private DateTime bAddtime; private double bmoney; private double bSubmoney; } } Category.cs:书籍类别实体类 namespace BMS { ///<summary> ///书籍类别实体类 ///</summary> publicclass Category { private int cId; public int CId { get { return cId; } set { cId= value; } } private string cName; public string CName { get { return cName; } set { cName= value; } } private string cRemark; public string CRemark { get { return cRemark; } set { cRemark= value; } } private bool cIsDel; public bool CIsDel { get { return cIsDel; } set { cIsDel= value; } } private DateTimecAddTime; public DateTimeCAddTime { get { return cAddTime; } set { cAddTime= value; } } private int cParentId; public int CParentId { get { return cParentId; } set { cParentId= value; } } } }
Form.cs
namespace BMS
{
publicpartial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//窗体加载事件:窗体加载的同时,LoadBooks,LoadCateCbo,LoadCateCboU过程被调用实现
private void Form1_Load(object sender, EventArgse)
{
LoadBooks();
LoadCateCbo();
LoadCateCboU();
}
///<summary>
///加载书籍列表
///</summary>
private void LoadBooks()
{
string sqlStr= "select b_id,c_name,b_title,b_content,b_author,b_addtime,b_cidfrom Book inner join Category on b_cid =c_cid where b_isdel=0";
DataTable dt = SqlHelper.GetDataTable(sqlStr);
dgvBooks.DataSource =dt;
}
///<summary>
///加载搜索区,类别下拉框数据
///</summary>
private void LoadCateCbo()
{
string sqlStr = "select * from Category where c_Isdel = 0";
DataTable dt = SqlHelper.GetDataTable(sqlStr);//查询未删除的分类
foreach (DataRowdrin dt.Rows)//循环生成类别实体(将行转化为实体对象)
{
Category modle = newCategory();
//数据表中的某项数据有可能是Null,像下面一个可以判断
if (dr["c_id"]!= null)
{
modle.CId =Convert.ToInt32(dr["c_id"]); //注意这种转化格式【前缀形式】
//convert这个类是一个转换类能将任何类型的对象转换成任何一个类型
}
modle.CName=dr["c_name"].ToString();//注意这种转换格式【后缀形式】
modle.CRemark=dr["c_remark"].ToString();
modle.CIsDel=bool.Parse(dr["c_isdel"].ToString());
modle.CAddTime=Convert.ToDateTime(dr["c_addtime"]);
modle.CParentId=Convert.ToInt32(dr["c_parentid"]);
cboCate.Items.Add(modle);//把实体对象添加到下拉框中
}
cboCate.DisplayMember ="CName";
cboCate.ValueMember="CId";
cboCate.SelectedIndex= 0;//【效果:最初的时候,下拉框中有数据】
}
private void LoadCateCboU()//利用绑定的方式
{
string sqlStr = "select * from Category where c_Isdel = 0";
DataTabledt =SqlHelper.GetDataTable(sqlStr);//查询未删除的分类
cboCateU.DataSource=dt;
cboCateU.DisplayMember="c_name";
cboCateU.ValueMember="c_id";
cboCateU.SelectedIndex= 0;
}
///<summary>
///搜索按钮点击事件
///</summary>
///<param name="sender"></param>
///<param name="e"></param>
private void btnSearch_Click(objectsender, EventArgse)
{
//获得关键字文本框内容,并去除两边的空格
string strKeyWord=txtKey.Text.Trim();//Trim()方法用于去掉字符串中间包含的空格
//获得下拉框选中项,转成Category类型,并获得类型ID
int cateId= ((Category)cboCateU.SelectedItem).CId;//并不是每个类型都可以转成Category【见图
string sqlStr = "select b_id,c_name,b_title,b_content,b_author,b_addtimefrom Book inner join Category on b_cid=c_cid where b_cid=@cid";//数据库那边的参数,下面要用到parameter
//如果关键字不为空,则向sql语句追加查询条件
if (!string.IsNullOrEmpty(strKeyWord))//字符串不为空,我们最好用【IsNullOrEmpty字段来判断】
{
sqlStr+= "and b_title like '%" + strKeyWord+"%'";
}
System.Data.SqlClient.SqlParametersp= newSystem.Data.SqlClient.SqlParameter("@cid",SqlDbType.Int);
DataTable dt = SqlHelper.GetDataTable(sqlStr,sp);
dgvBooks.DataSource=dt;
}
///<summary>
///书籍列表的单元格点击事件方法
///</summary>
///<param name="sender"></param>
///<param name="e"></param>
private void dgvBooks_CellClick(objectsender,DataGridViewCellEventArgse)//通过事件方法的参数e可以拿到这个方法
{
int rowIndex= e.RowIndex;//选中单元格所在行的下标
string bId = dgvBooks.Rows[rowIndex].Cells[0].Value.ToString();
// dgvBooks.Rows[rowIndex]表示行集合;Cells[0]表示行集合中的第一个单元格
//所以这句表示:所在行的第一个单元格里面的值转化成成string类型;行集合
lblID.Text =bId;
txtTitle.Text=dgvBooks.Rows[rowIndex].Cells[2].Value.ToString();
txtAuthor.Text =dgvBooks.Rows[rowIndex].Cells[4].Value.ToString();
txtContent.Text=dgvBooks.Rows[rowIndex].Cells[3].Value.ToString();
cboCateU.SelectedValue=dgvBooks.Rows[rowIndex].Cells[6].Value.ToString();
}
//修改按钮点击事件
private void btnUpdate_Click(object sender, EventArgse)
{
string cId = lblID.Text;
string bTitle = txtTitle.Text.Trim();//首先拿到书籍名称和书籍ID等内容
string bCid = cboCateU.SelectedValue.ToString();
string bAuthor = txtAuthor.Text.Trim();
string bContent = txtContent.Text.Trim();
string sqlStr = "update book setb_title=@title,b_cid=@cid;b_author=@aut,b_content=@content whereb_id=@bid";
SqlParameter[] paras={
new SqlParameter("@title",SqlDbType.Varchar),
new SqlParameter("@cid",SqlDbType.Int),
new SqlParameter("@aut",SqlDbType.VarChar),
new SqlParameter("@content",SqlDbType.VarChar),
new SqlParameter("@id",SqlDbType.Int),
};
//为参数数组中的每个参数赋值
paras[0].Value=bTitle;
paras[1].Value=bCid;
paras[2].Value=bAuthor;
paras[3].Value=bContent;
paras[4].Value=bId;
int res = SqlHelper.ExecNonQuery(sqlStr,paras);//调用SqlHelper中的非查询语句
if (res> 0)
{//如果修改成功,则刷新列表
LoadBooks();
}
else
{
MessageBox.Show("执行失败");
}
}
}
}
namespace BMS
{
publicpartial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//窗体加载事件:窗体加载的同时,LoadBooks,LoadCateCbo,LoadCateCboU过程被调用实现
private void Form1_Load(object sender, EventArgse)
{
LoadBooks();
LoadCateCbo();
LoadCateCboU();
}
///<summary>
///加载书籍列表
///</summary>
private void LoadBooks()
{
string sqlStr= "select b_id,c_name,b_title,b_content,b_author,b_addtime,b_cidfrom Book inner join Category on b_cid =c_cid where b_isdel=0";
DataTable dt = SqlHelper.GetDataTable(sqlStr);
dgvBooks.DataSource =dt;
}
///<summary>
///加载搜索区,类别下拉框数据
///</summary>
private void LoadCateCbo()
{
string sqlStr = "select * from Category where c_Isdel = 0";
DataTable dt = SqlHelper.GetDataTable(sqlStr);//查询未删除的分类
foreach (DataRowdrin dt.Rows)//循环生成类别实体(将行转化为实体对象)
{
Category modle = newCategory();
//数据表中的某项数据有可能是Null,像下面一个可以判断
if (dr["c_id"]!= null)
{
modle.CId =Convert.ToInt32(dr["c_id"]); //注意这种转化格式【前缀形式】
//convert这个类是一个转换类能将任何类型的对象转换成任何一个类型
}
modle.CName=dr["c_name"].ToString();//注意这种转换格式【后缀形式】
modle.CRemark=dr["c_remark"].ToString();
modle.CIsDel=bool.Parse(dr["c_isdel"].ToString());
modle.CAddTime=Convert.ToDateTime(dr["c_addtime"]);
modle.CParentId=Convert.ToInt32(dr["c_parentid"]);
cboCate.Items.Add(modle);//把实体对象添加到下拉框中
}
cboCate.DisplayMember ="CName";
cboCate.ValueMember="CId";
cboCate.SelectedIndex= 0;//【效果:最初的时候,下拉框中有数据】
}
private void LoadCateCboU()//利用绑定的方式
{
string sqlStr = "select * from Category where c_Isdel = 0";
DataTabledt =SqlHelper.GetDataTable(sqlStr);//查询未删除的分类
cboCateU.DataSource=dt;
cboCateU.DisplayMember="c_name";
cboCateU.ValueMember="c_id";
cboCateU.SelectedIndex= 0;
}
///<summary>
///搜索按钮点击事件
///</summary>
///<param name="sender"></param>
///<param name="e"></param>
private void btnSearch_Click(objectsender, EventArgse)
{
//获得关键字文本框内容,并去除两边的空格
string strKeyWord=txtKey.Text.Trim();//Trim()方法用于去掉字符串中间包含的空格
//获得下拉框选中项,转成Category类型,并获得类型ID
int cateId= ((Category)cboCateU.SelectedItem).CId;//并不是每个类型都可以转成Category【见图
string sqlStr = "select b_id,c_name,b_title,b_content,b_author,b_addtimefrom Book inner join Category on b_cid=c_cid where b_cid=@cid";//数据库那边的参数,下面要用到parameter
//如果关键字不为空,则向sql语句追加查询条件
if (!string.IsNullOrEmpty(strKeyWord))//字符串不为空,我们最好用【IsNullOrEmpty字段来判断】
{
sqlStr+= "and b_title like '%" + strKeyWord+"%'";
}
System.Data.SqlClient.SqlParametersp= newSystem.Data.SqlClient.SqlParameter("@cid",SqlDbType.Int);
DataTable dt = SqlHelper.GetDataTable(sqlStr,sp);
dgvBooks.DataSource=dt;
}
///<summary>
///书籍列表的单元格点击事件方法
///</summary>
///<param name="sender"></param>
///<param name="e"></param>
private void dgvBooks_CellClick(objectsender,DataGridViewCellEventArgse)//通过事件方法的参数e可以拿到这个方法
{
int rowIndex= e.RowIndex;//选中单元格所在行的下标
string bId = dgvBooks.Rows[rowIndex].Cells[0].Value.ToString();
// dgvBooks.Rows[rowIndex]表示行集合;Cells[0]表示行集合中的第一个单元格
//所以这句表示:所在行的第一个单元格里面的值转化成成string类型;行集合
lblID.Text =bId;
txtTitle.Text=dgvBooks.Rows[rowIndex].Cells[2].Value.ToString();
txtAuthor.Text =dgvBooks.Rows[rowIndex].Cells[4].Value.ToString();
txtContent.Text=dgvBooks.Rows[rowIndex].Cells[3].Value.ToString();
cboCateU.SelectedValue=dgvBooks.Rows[rowIndex].Cells[6].Value.ToString();
}
//修改按钮点击事件
private void btnUpdate_Click(object sender, EventArgse)
{
string cId = lblID.Text;
string bTitle = txtTitle.Text.Trim();//首先拿到书籍名称和书籍ID等内容
string bCid = cboCateU.SelectedValue.ToString();
string bAuthor = txtAuthor.Text.Trim();
string bContent = txtContent.Text.Trim();
string sqlStr = "update book setb_title=@title,b_cid=@cid;b_author=@aut,b_content=@content whereb_id=@bid";
SqlParameter[] paras={
new SqlParameter("@title",SqlDbType.Varchar),
new SqlParameter("@cid",SqlDbType.Int),
new SqlParameter("@aut",SqlDbType.VarChar),
new SqlParameter("@content",SqlDbType.VarChar),
new SqlParameter("@id",SqlDbType.Int),
};
//为参数数组中的每个参数赋值
paras[0].Value=bTitle;
paras[1].Value=bCid;
paras[2].Value=bAuthor;
paras[3].Value=bContent;
paras[4].Value=bId;
int res = SqlHelper.ExecNonQuery(sqlStr,paras);//调用SqlHelper中的非查询语句
if (res> 0)
{//如果修改成功,则刷新列表
LoadBooks();
}
else
{
MessageBox.Show("执行失败");
}
}
}
}
SqlHelper.cs
namespace BMS
{
publicstatic class SqlHelper
{
private static string conStr = ConfigurationManager.ConnectionStrings["conStr"].ConnectionString;
private static SqlConnection conn;
///<summary>
///连接通道属性
///</summary>
public static SqlConnection Conn
{
get
{
if(conn==null || conn.State==ConnectionState.Broken)
{
conn=new SqlConnection(conStr);
}
return conn;
}
}
///<summary>
///获取数据表
///</summary>
///<param name="sqlStr">查询语句</param>
///<param name="paras">参数数组</param>
///<returns>结果表</returns>
public static DataTable GetDataTable(string sqlStr,params SqlParameter[] paras)
{
//select * from U where id>@ddd带数据库的这种参数
//创建命令对象(查询语句,连接通道属性)
SqlCommand cmd= new SqlCommand(sqlStr,Conn);
if (paras!= null&¶s.Length> 0)//如果sql语句有参数
{
cmd.Parameters.AddRange(paras);//为命令对象添加参数数组
//foreach(SqlParameter sp in paras){
// cmd.Parameters.Add(sp);
//}//第二种方法
}
SqlDataAdapter da= new SqlDataAdapter(cmd);//查询多行数据用卡车
DataTabledt = newDataTable();
try
{
da.Fill(dt);
}
catch (Exception ex)
{
throw ex;
}
return dt;
}
///<summary>
/// /执行非查询语句是来这里调用
///</summary>
///<param name="sqlStr"></param>
///<param name="paras"></param>
///<returns></returns>
public static void OpenDB()
{
conn.Open();
}
publicstatic void CloseDB()
{
conn.Close();
}
public static int ExecNonQuery(stringsqlStr,SqlParameter[]paras)
{//执行非查询语句是来这里调用
SqlCommand cmd= new SqlCommand(sqlStr,Conn);
if (paras != null && paras.Length> 0)
{
cmd.Parameters.AddRange(paras);
}
OpenDB();
int res = 0;
try
{
res = cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
throw ex;
}
finally
{
CloseDB();
}
return res;
}
}
}
宏观简析
Book.cs
ClassBook{ …… }//书籍实体类
Category.cs
ClassCategory{ …… }//书籍类别实体类
SqlHelper.cs
ClassSqlHelper
OpenDB(){ };
CloseDB(){};
stringconStr = ConfigurationManager.ConnectionStrings[*].ConnectionString;//连接通道
SqlConnectionconn;//属性中进行判断(conn==null||conn.State=ConnectionState.Broken)
DataTableGetDataTable() //获取数据表
SqlCommandcmd = ;
if(paras!=null&¶s.Length>0){……} //
cmd.Parameters.AddRange(paras);
newSqlDataAdapter da = ;
newDataTable dt = ;
Fill(dt);//该处可以用try-catch
intExecNonQuery(){ }
SqlCommandcmd = ;
if(paras!=null&¶s.Length>0){……}
OpenDB();
intres = ;
cmd.ExecuteNonQuery();//该处可以用try-catch
连接->数据表->sql命令
Form1
Form1_Load(){
LoadBooks()
//
加载书籍列表
string sqlStr =
DataTable dt =SqlHelper.GetDataTable(sqlStr);
dgvBooks.DataSource= dt;
LoadCateCbo()
//
加载搜索区,类别下拉框数据
string sqlStr =
DataTable dt =SqlHelper.GetDataTable(sqlStr);
foreach (DataRowdr in dt.Rows){ …… }
//
★
循环生成类别实体(
将行转化为实体对象)
LoadCateCboU()
//
利用绑定的方式
string sqlStr =
DataTable dt =SqlHelper.GetDataTable(sqlStr);
cboCateU.DataSource=dt;//关键:上面用foreach方式实现,这里一句话实现
……
btnSearch_Click()
//
搜索按钮点击事件
txtKey.Text.Trim()
((Category)cboCateU.SelectedItem).Cid
string sqlStr =
dgvBooks_CellClick()
e.RowIndex
dgvBooks.Rows[rowIndex].Cells[0].Value.ToString()
void btnUpdate_Click()
lblID.Text/txtTitle.Text.Trim()/cboCateU.SelectedValue.Trim()……
//
首先拿到书籍名称和书籍
ID
等内容
sqlStr = ;
SqlParameter[] paras ={newSqlParameter()……}
paras[0…1].Value = bTitle;
if……else……
}
相应细节
txtKey.Text.Trim() //
获得文本框的内容
,并用Trim方法用于去掉字符串中间包含的空格
((Category)cboCateU.SelectedItem).Cid //获得下拉框选中项,转成Category类型,并获得类型ID
IsNullOrEmpty 用于判断字符串是否为空
SelectedIndex=0; //使下拉框中最初是有数据的
e.RowIndex; //选中单元格所在行的下标
dgvBooks.DataSource //DataSource是数据绑定控件,用于指定数据源,比较常用的是DataTable
//DataSource可以是任何 System.Collections.IEnumerable 对象,
关于DataSource
conn.State //连接状态
cmd.Parameters.AddRange(paras);//为命令对象添加参数数组