首页 > 代码库 > 【ADO.NET】8、DataSet的使用
【ADO.NET】8、DataSet的使用
SqlDataReader 适用于大型数据的读取,它是一条一条的读取,读取出来的数据是存放在服务器上
当正在读取数据的时候,突然与服务中断,将无法读取后面的数据
DataSet 适用于小型数据的读取,它是一次将所有数据读取并存放到本机程序的内存当中,占内存
当正在读取数据的时候,突然与服务中断,数据可继续读取
DataSet可存放若干个表(DataTable),每个表有若干个行(DataRow)
private void button3_Click(object sender, EventArgs e) //单击事件 { string Str = ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString; using (SqlConnection conn = new SqlConnection(Str)) { conn.Open(); using (SqlCommand cmd = conn.CreateCommand()) { cmd.CommandText = "select * from T_Age"; DataSet dataset = new DataSet(); //创建一个DataSet集,用于存放查询到的数据 SqlDataAdapter adapter = new SqlDataAdapter(cmd); //指定要执行的语句 adapter.Fill(dataset); //将查询到的数据填充到dataset中 DataTable table = dataset.Tables[0]; //查询第一张表 for (int i = 0; i < table.Rows.Count; i++) //遍历每一行,DataTable包含若干个行 { DataRow row = table.Rows[i]; //遍历每一行,得到每一行的内容 string name = Convert.ToString(row["Name"]); //查询当前行的 Name 列的数据 MessageBox.Show(name); //显示内容 } } } }
row["Name"]="xgao"; 更新行
table.Rows.Remove(); 删除行
table.NewRow(); 新增行
private void button3_Click(object sender, EventArgs e) //单击事件 { string Str = ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString; using (SqlConnection conn = new SqlConnection(Str)) { conn.Open(); using (SqlCommand cmd = conn.CreateCommand()) { cmd.CommandText = "select * from T_Age"; DataSet dataset = new DataSet(); SqlDataAdapter adapter = new SqlDataAdapter(cmd); adapter.Fill(dataset); DataTable table = dataset.Tables[0]; DataRow row = table.Rows[0]; row["Name"]="小高"; //将第一行的 Name 字段,更改为 "小高" table.Rows.RemoveAt(1); //删除第二行 DataRow dr = table.NewRow();//增加新行 SqlCommandBuilder builder = new SqlCommandBuilder(adapter) //自动生成操作命令 adpter.Update(dataset); } } } }
有XML架构(XSD)的DataSet
本质上就是DataSet,但多了一个架构的定义
添加 - 新建项 - 数据集
将表从服务器资源管理器拖放到DataSet(数据集)中,注意拖放过程是自动根据表结构生成强类型DataSet等类,
没有把数据也拖过来,程序还是连的那个数据库,自动将数据库连接字符串写在了App.Config中
注意:表一定要设置有主键,被取值的列一定要有值
弱点:当表的字段增加时,就需要重新配置生成
代码中使用DataSet示例(mydo表): mydoTableAdapter adapter = new mydoTableAdapter();
如何得知Adapter的类名?选中DataSet中的下半部分的Adapter,Name属性就是类名,需要右键点击类名 - 解析
取得所有数据:adapter.GetData(),
例子程序:遍历显示所有数据
i<adapter.GetData().Count;
adapter.GetData()[i].Age;
常见问题:类名一般为: 表名+TableAdapter,表名+DataTable,表名+Row,然后用"解析"来填充类名
实验一 :操作 mydo 表,遍历出所有 username 字段的值 ----- 查询
private void button7_Click(object sender, EventArgs e) { mydoTableAdapter adapter = new mydoTableAdapter(); //创建一个TableAdapter SQL封装.DataSet1.mydoDataTable data = http://www.mamicode.com/adapter.GetData(); //获取数据,强类型DataTable>
SQL封装.DataSet1.mydoDataTable //为什么这么长?因为 mydoDataTable 类是在 DataSet1 类里面定义的
SQL封装: 程序集名称 namespace
DataSet1: 外部类的类名
实验二:操作 T_Age 表,遍历出所有 Name 与 Age 字段的值 ----- 查询
private void button1_Click(object sender, EventArgs e) { T_AgeTableAdapter adapter = new T_AgeTableAdapter(); wf强类型.T_Age.T_AgeDataTable myage = adapter.GetData(); for (int i = 0; i < myage.Count; i++) { wf强类型.T_Age.T_AgeRow data = http://www.mamicode.com/myage[i];"姓名:{0},年龄:{1}", data.Name, data.Age); MessageBox.Show(msg); } }
实验三:操作 T_Age 表,修改T_Age表里面的Name值 ------ 更新 Update
private void button1_Click(object sender, EventArgs e) { T_AgeTableAdapter adapter = new T_AgeTableAdapter(); wf强类型.T_Age.T_AgeDataTable myage = adpater.GetData(); for (int i = 0; i < myage.Count; i++) { wf强类型.T_Age.T_AgeRow data = http://www.mamicode.com/myage[i];"姓名:{0},年龄:{1}", data.Name, data.Age); MessageBox.Show(msg); } myage[0].Name = "test"; //将表的Name字段的第一条数据改为 test adapter.Update(myage); //针对myage表更新数据到服务器上 }
常见问题:错误提示:当传递有已修改行的DataRow集合时,更新要求有交接的UpdateCommand
原因:表中没有加主键,为表中某个字段设置为主键即可
实验四:操作 T_Age 表,往 Name 与 Age 字段插入值 ------- 插入 Insert
private void button3_Click(object sender, EventArgs e) { T_AgeTableAdapter adapter = new T_AgeTableAdapter(); adapter.Insert("zhangsan", 23); //直接调用 insert() 方法就可以插入数据 MessageBox.Show("插入成功!"); }
实验五:操作 T_Age 表,删除表里面的某行数据 ------- 删除 delete
private void button3_Click(object sender, EventArgs e) { T_AgeTableAdapter adapter = new T_AgeTableAdapter(); adapter.delete(3,"zhangsan", 23); //删除指定的数据,比较麻烦,都须要指定 MessageBox.Show("删除成功!"); }
//----------------强类型 DataSet数据的读取
// 强类型 DataSet
NewsDataSet ds = new NewsDataSet(); var daNews = new NewsDataSetTableAdapters.newsTableAdapter(); var daCate = new NewsDataSetTableAdapters.categoryTableAdapter(); daNews.Fill(ds.news); daCate.Fill(ds.category); this.gv1.DataSource = ds.category; this.gv1.DataBind(); this.gv2.DataSource = ds.news; this.gv2.DataBind();
//---------------- 更精简的 强类型 DataSet数据的读取
this.gv1.DataSource = new NewsDataSetTableAdapters.categoryTableAdapter().GetCate(); this.gv1.DataBind();
//----------------强类型 DataSet 的插入,删除,更改
new NewsDataSetTableAdapters.categoryTableAdapter().Insert("测试类型"); new NewsDataSetTableAdapters.categoryTableAdapter().Delete(13); new NewsDataSetTableAdapters.categoryTableAdapter().Update("修改后的", 16);
1.在数据集当中 右键 - 添加 - Query - 使用 SQL 语句 选择操作的类型,如:select,insert,update,delete
如下:保存名为 GetDataByAge
SELECT id, Name, Age FROM T_Age WHERE (Age > @Age)
2.使用
T_AgeTableAdapter adapter = new T_AgeTableAdapter(); wf强类型DataSet.T_Age.T_AgeDataTable data = http://www.mamicode.com/adapter.GetDataByAge(30); //传值 >
在强类型DataSet中,里面所用到的 adapter.Insert(),之类的对数据库进行操作的,它的工作模式如下:
1.插入数据前,先判断连接是否打开,如果没打开,则打开
2.完成数据插入后,再判断,原先(不是程序自动打开的那个)的连接是否关闭,如果关闭则关闭,否则将继续打开
默认连接是关闭的,所以当插入数据的时候会这样工作:
1.自动打开连接,插入数据
2.完成数据插入后,发现原现的连接是关闭的,所以则关闭
从中可以看出我们只要在程序判断前,将连接打开,后面程序将不会自动关闭连接,如果在做批量插入的时候,可以在循环语句前,先将连接打开,循环后,再将连接关闭,这样将会大大加快数据的插入所耗时间
实例:
新建一个 Stopwatch 表,字段为 id int,Name nvarchar(20),Age nvarchar(20)
没有做优化前,总耗时 12 秒, 做优化后,总耗时 2 秒
private void button1_Click(object sender, EventArgs e) //单击事件 { Stopwatch sw = new Stopwatch(); sw.Start(); StopwatchTableAdapter adapter = new StopwatchTableAdapter(); adapter.Connection.Open(); //循环前,先打开连接 for (int i = 0; i < 3000; i++) { adapter.Insert(i.ToString(), i.ToString(), i.ToString()); //插入数据 } adapter.Connection.Close(); //循环后,再关闭连接 sw.Stop(); MessageBox.Show(sw.Elapsed.ToString()); //输出耗时时间,以秒为单位 }
在已建好的DataTable中添加一列数据
public DataTable GetOneTwoNum() { DataTable dt = SoftwareTypeBLL.GetOneTwoNum(); // 获得一个DataTable DataColumn dc = new DataColumn("TwoName", typeof(System.String)); // 设置一列 dt.Columns.Add(dc); // 将一列添加到 Datatable 中 foreach (DataRow row in dt.Rows) { string TwoStr = "随便内容"; row["TwoName"] = TwoStr; // 将新内容添加到指定的列 } return dt; //返回修改后的 DataTable }
【ADO.NET】8、DataSet的使用