DataSet:
1,介绍:DataSet是ADO.NET的中心概念。可以把DataSet当成内存中的数据库,DataSet是不依赖于数据库的独立数据集合。所谓独立,就是说,即使断开数据连接,或者关闭数据库,DataSet依然是可用的,DataSet在内部是用XML来描述数据的,由于XML是一种与平台无关、与语言无关的数据描述性语言,而且可以描述复杂关系的数据,比如父子关系的数据,所以DataSet实际上可以容纳具有复杂关系的数据,而且不再依赖于数据库链路。DataSet支持多表、表间关系、数据约束等,和关系数据库的模型基本一致。
2,DataSet对象的三大特性
(1)独立性。DataSet独立于各种数据源。
(2)离线(断开)和连接。
(3) DataSet对象是一个可以用XML形式表示的数据视图,是一种数据关系视图。
3,DataSet的使用方法:
(1) 把数据库中的数据通过DataAdapter对象填充DataSet。
(2) 通过DataAdapter对象操作DataSet实现更新数据库。
(3) 把XML数据流或文本加载到DataSet。
使用Dataset的几个步骤
第1步,创建到数据源的连接:
SQLConnection con =new SQLConnection("server=localhost;uid=sa;pwd=;database=pubs");
第2步,创建DataSetCommand对象,指定一个存储过程的名字或者一个SQL语句,指定数据链路;
SQLDataSetCommand cmd =new SQLDataSetCommand("SELECT * FROM Authors", con);
第3步,创建一个Dataset对象
DataSet ds = new DataSet();
第4步,调用DataSetCommand的FillData方法,为Dataset填充数据。注意:数据链路没有必要是打开的。如果数据链路是关闭状态,FillData函数会打开它,并在FillData之后关闭数据链路。如果数据链路本来就是打开的,在FillData之后,数据链路依然保持打开状态。
int iRowCount = cmd.FillDataSet(ds, "Authors");
第5步,操作数据。由于FillData返回了记录的个数,我们可以构造一个循环,来操纵Dataset中的数据。
for(int i=0; i< iRowCount; i++){
DataRow dr = ds.Tables[0].Rows[i];
Console.WriteLine(dr["au_lname"]);
}
C#代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Data.SqlClient;
using System.Data;
namespace WPFDemo01
{
/// <summary>
/// ADOBasic.xaml 的交互逻辑
/// </summary>
public partial class ADOBasic : Window
{
public ADOBasic()
{
InitializeComponent();
}
private void btnLink_Click(object sender, RoutedEventArgs e)
{
//对实现了IDisposible接口的,使用using关键字,它能控制对资源的释放,具体的自行百度。语法是
//using(类型d = new (这里面指的是创建对象)......){.................}他可以自动回收资源,不用自己关闭数据库
//以后都这么写,conn.close();的方法前面程序挂掉了,那么数据库就没有关,这样时间久了会造成数据库泄露
//SqlConnection建立和数据库的连接
//1.第一种,
//ExecuteNonQuery()通常用来执行Update,Delete,Insert语句,就如单词所示NonQuery,非查询!
//using (SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=DemoDB;User ID=sa;Password=540469505"))
//{
// conn.Open();
// MessageBox.Show("数据库连接成功!");
// //通过连接创建一个向数据库发命令(command)的对象
// using(SqlCommand cmd = conn.CreateCommand())
// {
// //CommandText为要执行的sql语句
// cmd.CommandText = "insert into T_Students(id,name,age,aihao,height) values (101,‘刘亦菲‘,23,‘北京吧‘,170);";
// cmd.ExecuteNonQuery(); //开始执行
// }
//}
//2.第二种,
//查询用ExecuteScalar()返回的是一行一列的值
//using (SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=DemoDB;User ID=sa;Password=540469505"))
//{
// conn.Open();
// using(SqlCommand cmd = conn.CreateCommand())
// {
// //例1:
// //cmd.CommandText="select count(*) from T_Students";
// //ExecuteScalar()返回的是一行一列的值使用该类型,意思就是查询的结果只有一个,
// //因为其返回的是object类型,所以根据我们返回的实际类型可以进行强制类型转换,
// //这里一定要写对对应类型,比如数据库中的varchar类型对应C#中的是string,
// //bigint类型对应的是long类型
// //int i =(int)cmd.ExecuteScalar();
// //MessageBox.Show("查询到结果数为:"+i+"条");
// //例2:
// //cmd.CommandText = "select ‘dafa‘";
// //string s = (string)cmd.ExecuteScalar();
// //MessageBox.Show(s);
// //例3:
// //本数据库中自增长字段为addId,其值是数据库自动分配的,
// //那么我们如何得知本数据的addId是多少呢?
// cmd.CommandText = "insert into T_Students(id,name,age,aihao,height) output inserted.addId values (10000,‘离死‘,102,‘‘,80)";
// int i = (int)cmd.ExecuteScalar();
// MessageBox.Show("当前addId为:"+i);
// }
//}
//3.第三种,
//执行有多行结果的结果集用ExecuteReader,同样是实现IDisposible接口的
//SqlDataReader reader = cmd.ExecuteReader();.....
//while(reader.Reader())
//{
//Console.writeLine(reader.GetString(1));
//}这里要和注意,该查询结果是放在数据库中的,没有放到
//客户端,初始指针指向第一条数据之前,每调用一次Reader指针
//下移一条,只要没有移到最后一条之后,就一直返回true
//reader的GetString、GetInt32的方法只接受整数参数,
//也就是序号,用GetOrdinal方法根据列名动态得到序号
using(SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=DemoDB;User ID=sa;Password=540469505"))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select * from T_Students;";
using (SqlDataReader reader = cmd.ExecuteReader())
{
while(reader.Read())
{
string name = reader.GetString(1); //根据数据库返回值类型写C#对应类型,这里面的参数表示返回该行的第几列
int age = reader.GetInt32(2); //这里的类型对应有点麻烦,要注意
MessageBox.Show("名字是:"+name+" "+"年龄是:"+age);
}
}
}
}
MessageBox.Show("执行完成~!");
}
private void btnSearch_Click(object sender, RoutedEventArgs e)
{
using(SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=DemoDB;User ID=sa;Password=540469505"))
{
conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
//此字符串拼接方法,如果这里输入“1‘ or ‘1‘=‘1”,则会查出所有的结果,造成了SQL注入漏洞
//cmd.CommandText = "select * from T_Students where name = ‘"+txtPerson.Text+"‘";
//@Name是占位符,表示我这里需要一个Name的值,这样看起来更有意义,但是name这个词可以换成其他的任意词
cmd.CommandText = "select * from T_Students where Name=@Name or Age=@Age";
//用法1:
//cmd.Parameters.AddWithValue("@Name",txtPerson.Text);
//用法2:推荐使用
cmd.Parameters.Add(new SqlParameter("@Name",txtPerson.Text));
//注意如果是别的类型的注意转换类型
cmd.Parameters.Add(new SqlParameter("@Age", Convert.ToInt32(txtPerson.Text)));
//此语句也可以用在如下语句等
//insert into......values(@Name,@Age...)
//delete ...... where ID=@idAdd
//注意"@参数"不能用在替换表名、字段名、select之类的关键字等。
//如下都是不可以的!
//select age from @TableName..
//select @AgeName from table...
using(SqlDataReader reader = cmd.ExecuteReader())
{
while(reader.Read())
{
//GetInt32获得的是int类型
//GetInt64获得的是long类型(数据库中是bigint)
int id = reader.GetInt32(0);
string name = reader.GetString(1);
int age = reader.GetInt32(2);
string address = reader.GetString(3);
int addId = reader.GetInt32(4);
MessageBox.Show(id.ToString()+" "+name+" "+age.ToString()+" "+address+" "+addId.ToString());
}
}
}
}
}
//4.第四种
//SqlDataReader是连接相关的,SqlDataReader中的查询结果并不是放到程序中,
//而是放在数据库服务器中,SqlDataReader只是相当于放了一个指针(游标),只能
//读取当前游标指向的行,一旦连接断开就不能再读取。这样做的好处就是无论查询
//结果有多少条,对程序占用的内存都几乎没有影响。
//SqlDataReader对于小数据量的数据来说带来的只有麻烦。ado.net中提供了数据集的
//机制,将查询结果填充到本地内存中,这样连接断开、服务器断开都不影响数据的读取。
//数据集的好处就是降低数据库服务器压力,编程也简单。
//DataSet dataset = new DataSet();
//SqlDataAdapter adapter = new SqlDataAdapter(cmd);
//adapter.Fill(dataset);
//DataSet包含若干表DataTable,DataTable包含若干行DataRow,
private void btnDataSet_Click(object sender, RoutedEventArgs e)
{
using (SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=DemoDB;User ID=sa;Password=540469505"))
{
conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select * from T_Students where age<@Age";
cmd.Parameters.Add(new SqlParameter("@Age",txtAge.Text));
//SqlDataAdapter是一个帮我们把SqlCommand查询的结果
//填充到DataSet中的一个类
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
//DataSet相当于本地的一个复杂集合(类似于List<int>)
DataSet dataset = new DataSet();
//执行cmd并且把SqlCommand查询的结果填充到DataSet
adapter.Fill(dataset);
//dataset可以放多个表,我们只放了一个表,所以下标为0
DataTable table = dataset.Tables[0];
//得到表中有多少行
DataRowCollection rows = table.Rows;
for (int i = 0; i < rows.Count; i++ )
{
//取出多行中的第i行
DataRow row = rows[i];
//分别去除第i行中的各个列的值
int age = (int)row["Age"];
string name = (string)row["Name"];
MessageBox.Show(name + ","+age);
}
}
}
}
}
}
学习笔记(9W)
原文:https://www.cnblogs.com/JKOBGHJ/p/9998386.html