在前面一讲中,我们应该已经熟悉了如何使用DataAdapter对象来进行数据更新,下面我们先进行一下总结,然后再讲解一下通过Command对象如何更新数据。
一、通过DataAdpater对象的Update方法
DataAdapter对象的update方法可以调用来自Dataset中的更改解析回数据源。其工作原理本质上还是通过执行所引用的Command对象进行更新的。当调用Update方法的时候,DataAdpater将分析出已经发生的变化,并执行相应的命令(insertCommand、updateCommand或者deleteCommand)。因此,要提供性能,就要尽可能的显示设置DataAdpater的命令。
当然,如果DataTable映射到单个数据表上,或者它是由单个表填充生产的,也可以利用CommandBuilder对象自动生成DataAdapter的DeleteCommand、InsertCommand和UpdateCommand。其方法是:先生成SqlCommandBuilder对象:SqlCommandBuilder scb=new SqlCommandBuilder(sqlDataAdpater);这样,就能够自动通过CommandBuilder来设置适配器sqlDataAdapter的命令形式:类似于sqlDataAdpter.UpdateCommand=scb.getUpdateCommand() 。
如果使用OleDb、Odbc、Oracle连接数据库,只需要做相应的调整就行了。
在使用CommandBuilder为DataAdapter生成Command命令更新数据源时,需要注意以下事项:
1、SelectCommand使用的select命令中必须包含主键(其实在数据表中如果声明了主键即可)
2、填充数据集时,必须要加载主键。方法如下:
da.Fill(ds, "dataTableName");
ds.Tables["dataTableName"].PrimaryKey=new DataColumns[]{ds.Tables["dataTableName"].Columns["ColulmnsName"]};
或者也可以这么做:
da.FillSchema(ds, SchemaType.Source, "dataTableName"); //加载表结构
//这里在加载表结构时也可以用DataReader.GetSchemaTable();
da.Fill(ds, "dataTableName"); //加载表数据
3、DataAdapter的MissingSchemaAction属性设置为AddWithKey
4、更新数据源成功后,使用ds的Acceptchanges方法,更新数据集。
二、通过Command对象进行更新
下面举个使用适配器进行数据更新的例子。
首先,为了不破坏了SQL2005上原有的示例数据库的数据,我们先使用“select * into salesreason from sales.salesreason”,将sales.salesreason表复制一份到dbo.salesreson中去。然后就对dbo.salesreson进行操作。
几个控件:customerid后面的的文本框 textBox1,下面分别是textBox2、textBox3以及右下角的textBox4.几个按钮:“数据插入”名为button1,下面依次是button2、button3;“< <”是button4,右边依次是5/6/7
“查找”是button8.
下面是详细代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
int i = 0; //用i来确定其坐在数据表的行号。一开始时i=0,则是表中的第一行
DataSet ds;
SqlDataAdapter sda;
string strcon = "Data Source=localhost; Initial Catalog=adventureWorks; Integrated Security=sspi";
string strsql = "select SalesReasonID,name,ReasonType from dbo.SalesReason";
SqlConnection scon;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
scon = new SqlConnection(strcon);
}
public void show(int i)
{
if (ds != null)
{
ds.Clear();
}
else
{
ds = new DataSet();
sda = new SqlDataAdapter(strsql,strcon);
}
sda.Fill(ds, "SalesReason");
textBox1.Text = ds.Tables["SalesReason"].Rows[i]["SalesReasonID"].ToString();
textBox2.Text = ds.Tables["SalesReason"].Rows[i]["Name"].ToString();
textBox3.Text = ds.Tables["SalesReason"].Rows[i]["ReasonType"].ToString();
}
private void button4_Click(object sender, EventArgs e)
{
i = 0;
show(i);
}
private void button5_Click(object sender, EventArgs e)
{
if (i != 0)
{
i--;
show(i);
}
else
MessageBox.Show("已经是第一条记录了");
}
private void button6_Click(object sender, EventArgs e)
{
if (i < ds.Tables["SalesReason"].Rows.Count - 1)
{
i++;
show(i);
}
else
MessageBox.Show("已经是最后一条记录了");
}
private void button7_Click(object sender, EventArgs e)
{
i=ds.Tables["SalesReason"].Rows.Count - 1;
show(i);
}
private void button8_Click(object sender, EventArgs e)
{
int k = 0;//用来确定要查找记录的下标
if (textBox4.Text.Trim() == "")
{
MessageBox.Show("查找内容不能为空");
}
else
{
for (k = 0; k < ds.Tables["SalesReason"].Rows.Count; k++)
{
if (ds.Tables["SalesReason"].Rows[k]["SalesReasonID"].ToString() == textBox4.Text)
{//找到了和textBox4中的id号相匹配的记录了,其行号为k
i = k;
show(i);
break;
}
}
}
if (k == ds.Tables["SalesReason"].Rows.Count)
MessageBox.Show("无此客户信息");
textBox4.Text = "";
}
private void button1_Click(object sender, EventArgs e)
{
SqlCommand sqlcmd = new SqlCommand("select count(*) from sales.SalesReason where SalesReasonID='" + textBox1.Text + "'", scon);
sqlcmd.Connection.Open();
int a = (int)sqlcmd.ExecuteScalar();//返回源表中与输入的客户id相等的个数
sqlcmd.Connection.Close();
if (a > 0)
{
MessageBox.Show("此客户已经存在,请重新插入");
return;
}
ds.Clear();
sda.Fill(ds, "SalesReason");
ds.Tables["SalesReason"].PrimaryKey = new DataColumn[] { ds.Tables["SalesReason"].Columns["SalesReasonID"] };
SqlCommandBuilder sqlCommandBuilder1 = new SqlCommandBuilder(sda);
DataRow dr = ds.Tables["SalesReason"].NewRow();
dr["SalesReasonID"] = Int32.Parse(textBox1.Text);
dr["name"] = textBox2.Text;
dr["ReasonType"] = textBox3.Text;
ds.Tables["SalesReason"].Rows.Add(dr);
sda.Update(ds, "SalesReason");
ds.AcceptChanges();
MessageBox.Show("数据插入成功");
}
private void button2_Click(object sender, EventArgs e)
{
for (int j = 0; j < ds.Tables["SalesReason"].Rows.Count; j++)
{
if (ds.Tables["SalesReason"].Rows[j]["SalesReasonID"].ToString() == "" &&
ds.Tables["SalesReason"].Rows[j]["SalesReasonID"].ToString() != ds.Tables["SalesReason"].Rows[i]["SalesReasonID"].ToString())
{
MessageBox.Show("此SalesReasonid已经存在,请重新输入");
textBox1.Text = "";
return;
}
}
ds.Clear();
sda.Fill(ds, "SalesReason");
ds.Tables["SalesReason"].PrimaryKey = new DataColumn[] { ds.Tables["SalesReason"].Columns["SalesReasonID"] };
SqlCommandBuilder sqlCommandBuilder1 = new SqlCommandBuilder(sda);
ds.BeginInit(); //挂起修改数据
ds.Tables["SalesReason"].Rows[i]["SalesReasonID"] = Int32.Parse(textBox1.Text);
ds.Tables["SalesReason"].Rows[i]["Name"] = textBox2.Text;
ds.Tables["SalesReason"].Rows[i]["ReasonType"] = textBox3.Text;
ds.EndInit(); //结束挂起
sda.Update(ds, "SalesReason");
ds.AcceptChanges();
MessageBox.Show("数据修改成功");
}
private void button3_Click(object sender, EventArgs e)
{
DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter(strsql,strcon);
da.Fill(ds, "SalesReason");
ds.Tables["SalesReason"].PrimaryKey = new DataColumn[] { ds.Tables["SalesReason"].Columns["SalesReasonID"] };
SqlCommandBuilder sqlCommandBuilder1 = new SqlCommandBuilder(da);
// da.DeleteCommand = sqlCommandBuilder1.GetDeleteCommand();
ds.Tables["SalesReason"].Rows[i].Delete();
da.Update(ds,"SalesReason");
ds.AcceptChanges();
MessageBox.Show("数据删除成功");
i = 0;
show(i);//删除成功后,重新显示第一条数据
}
}
}
如果使用SQL Command的方式来直接更新数据源,写起来就更简单了,举个例子,拿前面删除部分的例子来举例好了:
private void button3_Click(object sender, EventArgs e)
{
SqlCommand cmd=new SqlCommand();
cmd.Connection=scon;
cmd.CommandText="delete from dbo.SalesReason where SalesReasonID=' "+textBox1.Text+" ' ";
scon.Open();
cmd.ExecuteNonQuery();
scon.Close(); //更新完毕,下面代码刷新显示,将记录定位到第一行
i=0; refresh();
show(i);
MessageBox.Show("数据删除成功");
refresh();
}