Ado.net总结

Ado.net总结

Connetion对象

作用:

1. 连接数据库

2. 创建Command对象

3. 创建Transaction对象

重要属性

1. ConnectionString

2. State 其值包括 Closed Open

连接池

1. Ado.Net的连接池默认是打开的。如果数据库连接在60秒内未被再次使用,系统会自动关闭连接。当调用close方法时实际上是把连接放回到池中。

重要方法

1. Open()

2. Close()

3. CreateCommand()

4. BeginTransaction()

Command对象和DataReader对象

Command作用

1. 执行sql 语句

2. 执行存储过程

3. 执行视图

DataReader作用

1.装载结果集

创建Command对象的方法有三种

1. Command cmd = Con.CreateCommand();

2. Command cmd= new Command(sql,con);

3. Command cmd= new Command(sql,con,trans);

4. Command cmd= new Command();

重要知识点

1. cmd.ExecuteReader();

这个方法返回的结果集存储在DataReader中,它的游标是仅向前且只读的(流水游标)DataReader的read方法可以读取结果集数据

OleDbDataReader rdr = cmd.ExecuteReader();

while(rdr.read())

Conlole.write(rdr[“CustomerID”]);

2. OleDbDataReader读取数据的三种方式

1:rdr[“ColumnName”]

2:rdr[ColumnIndex];

3. OleDbDataReader的NextResult方法获取多个结果集

string strsql=”select * from t1;select * from t2”;

SqlCommand cmd = new SqlCommand(strsql,conn)

OleDbDataReader rdr = cmd.ExecuteReader();

do{

while(rdr.read()) {

Console.writeline(rdr[0]+rdr[1]);

}

Console.writeline();

}while(rdr.NextResult());

4. 关闭DataReader对象

尽可能迅速关闭DataReader对象是非常重要的,一个带有开放DataReader的Connection对象仍然被认为是锁定的。如果你在关闭一个DataReader之前试图打开第二个DataReader对象就会报错。例如:

SqlCommand cmd = new SqlCommand("select * form jobs",con);

SqlDataReader dr= cmd.ExecuteReader();

SqlCommand cmd1 = new SqlCommand("select * form jobs",con);

SqlDataReader dr1= cmd.ExecuteReader();

DataReader对象是出于性能方面的原因考虑的。如果需要在结果集的行之间前后移动就应该使用DataSet对象。

5. cmd.ExecuteNonQuery();

可以返回影响记录的行数,也可以不要返回值,主要用于执行增删改,不包括查询。

6.

Convert.ToInt32与int32.parse的区别

前一个是将差不多所有的类型转换为int32,而后以这只是将一个字符串形式的数转换为int32。

convert.toint32(1234.32)是正确的。 而int32.parse(1234.21)就不对了。

执行返回单个值的查询

OleDbCommand cmd = cn.CreateCommand();

cmd.CommandText=”select count(*) from Customers”;

int counts=Convert.ToInt32(cmd.ExecuteScalar());

7. 执行参数查询

参数标记是以@开头的变量

string sql=”select * from jobs where job_id=@id”;

OleDbCommand cmd=new OleDbCommand(sql,cn);

cmd.Parameters.add(“@id”,OleDbType.int);

cmd.Parameters[0].value=1;

OleDbDataReader rdr=cmd.ExecuteReader();

rdr.read();

8. 调用存储过程无输出参数

SqlCommand cmd= con.CreateCommand();

cmd.CommandText="procName";

cmd.CommandType =CommandType.StoredProcedure ;

cmd.Parameters.Add("@procParam",DbType.Int32);

cmd.Parameters[0].Value="5";

SqlDataReader dr1= cmd.ExecuteReader();

9. 调用存储过程有输出参数

Create porc test

@customerID int,

@outParam varchar(20) output

as

……

SqlCommand cmd= con.CreateCommand();

cmd.Connection =cn;

cmd.CommandText="{CALL test(?,?)}";

cmd.Parameters.Add("@customerID ",DbType.Int32);

cmd.Parameters.Add("@procParam",DbType.string);

cmd.Parameters[“@ customerID”].Value="5";

cmd.Parameters[“@procParam”].Direction=ParameterDirection.Output;

cmd.ExecuteNonExecute();

Console.writeline(Convert.ToInt32(cmd.Parameters[“@procParam”].Value));

10. 在Command中执行事务Transaction

SqlTransaction tran= con.BeginTransaction();

string sql="select * from t1";

//SqlCommand cmd = new SqlCommand(sql,con,tran);

SqlCommand cmd = con.CreateCommand();

cmd.Transaction=tran;

cmd.ExecuteNonQuery();

tran.Commit();

//tran.Rollback();

Command重要属性

CommandText

l CommandType .Text

l CommandType .StoredProcdure

l CommandType .TableDirect

CommandType

Connection

Parameters

Transaction

Command重要方法

CreateParameter()

ExecuteNonQuery()

ExecuteReader()

ExecuteScalar()

DataReader重要属性

FieldsCount

isClosed

DataReader重要方法

Read()

Close()

Parameter重要属性

DataType 参数对象的数据类型

DbType 参数的数据库数据类型sql

Direction

l Input

l Output

l ReturnValue

OleDbType OleDb数据类型

SourceColumn

SourceVersion

Value

DataAdapter对象

作用:DataAdapter类是ADO.NET对象模型中联机和脱机两部分的桥梁。可以使用DataAdapter将数据库的数据取出来放到DataSet中去,也可以将DataSet中的数据修改提交给数据库。

这里只介绍DataAdapter将数据库的数据取出来放到DataSet中去,后边在介绍将DataSet中的数据修改提交给数据库。

创建DataAdapter

注意使用相同连接的问题

方法1

不使用Connection,这种情况SqlDataAdapter每次建立一个Connection,使用后又关闭了Connection。

string constr="server=.;database=pubs;uid=sa;pwd=";

string sql="select * from jobs";

SqlDataAdapter adap= new SqlDataAdapter(sql,constr);

DataSet ds= new DataSet();

adap.Fill(ds);

dataGrid1.DataSource=ds.Tables[0].DefaultView;

方法2

使用Connection,每次使用相同的Connection

string constr="server=.;database=pubs;uid=sa;pwd=";

SqlConnection con= new SqlConnection(constr);

con.Open();

string sql="select * from jobs";

string sql1="select * from tt";

SqlDataAdapter adap= new SqlDataAdapter(sql,con);

SqlDataAdapter adap1= new SqlDataAdapter(sql1,con);

DataSet ds= new DataSet();

adap.Fill(ds);

dataGrid1.DataSource=ds.Tables[0].DefaultView;

1. 设计DataAdapter的目的是处理脱机数据

2. 在DataAdapter和DataSet之间没有直接连接,当数据Fill完成之后两者之间就没有连接了

adap.Fill(ds);

3. DataAdapter中包含用于向数据库回传存储在DataSet中的改动的更新逻辑,而且更新逻辑有我们自己控制。它们是

SelectCommand

InsertCommand

UpdateCommand

DeleteCommand

4. Fill方法

Adap.Fill(ds); //DataSet中的表名称默认为table table1 table2…

Adap.Fill(ds,”DataSetTableName”); //DataSet中的表名称为DataSetTableName

5. 多次调用Fill方法将数据装载到DataGrid中会出现数据重复显示,解决方法

1.每次重新new DataSet()

DataAdapter重要属性

SelectCommand

InsertCommand

UpdateCommand

DeleteCommand

DataAdapter重要方法

Fill()

Update()

DataSet,DataTable,DataRow,DataColumn对象

1. DataSet的特性

1. 处理脱机数据

2. 浏览、排序、搜索、过滤

3. 处理数据关系

4. 缓存更改

2. 创建DataSet对象

DataSet ds=new DataSet();

3. 填充数据集DataSet

SqlDataAdapter adap=new SqlDataAdapter(sql,con);

DataSet ds=new DataSet();

adap.Fill(ds,”tableName”);

4. DataTable对象和DataColumn对象

adap=new SqlDataAdapter("select * from tt",con);

adap.Fill(ds,"dstt");

DataTable dt=ds.Tables[0];

for(int i=0;i<dt.Columns.Count ;i++){

Console.WriteLine(dt.Columns[i].ColumnName);

}

foreach(DataColumn col in dt.Columns){

Console.WriteLine(col.ColumnName);

}

5. 查看DataAdapter返回的数据

DataRow对象:返回DataTable中的一行数据

adap=new SqlDataAdapter("select * from tt",con);

adap.Fill(ds,"dstt");

DataTable dt=ds.Tables[0];

DataRow dr=dt.Rows[0];

Console.WriteLine(dr[0]);

Console.WriteLine(dr[1]);

static void DisplayRow(DataRow row)

{

DataTable tbl=row.Table;

foreach(DataColumn col in tbl.Columns)

{

Console.WriteLine(col.ColumnName+row[col]);

}

}

foreach(DataRow row in tbl.Rows)

{

DisplayRow(row);

}

注意:DataRow没有Column属性,Column属性在DataTable中,通过

DataTable tbl=row.Table;得到DataTable

DataRow.RowState属性公开,如下表:

成员名称

说明

Added

该行已添加到 DataRowCollection 中,AcceptChanges 尚未调用。

Deleted

该行已通过 DataRow 的 Delete 方法被删除。

Detached

该行已被创建,但不属于任何 DataRowCollection。DataRow 在以下情况下立即处于此状态:创建之后添加到集合中之前;或从集合中移除之后。

Modified

该行已被修改,AcceptChanges 尚未调用。

Unchanged

该行自上次调用 AcceptChanges 以来尚未更改。

一个DataRow对象刚被创建之后其状态是Detached,是孤立的一个存在,所以建立了DataRow之后在DataRow中的单元填充了数据后还要通过DataTable.Rows.Add(DataRow)方法将此DataRow添加到DataTable,DataRow添加到DataTable后, 这个DataRow的状态就转变为Added。当修改了这个DataRow后,这个DataRow状态转为Modified,当用DataRow.Delete()方法删除DataRow后,DataRow状态将转为Deleted,不过此行还存在在DataTable中的,只是状态改变了,这时用DataTable.Rows.Count查看行数,跟删除前是一样的。只有在调用了DataTable.Remove(DataRow)方法后,此DataRow才被从DataTable移除,状态也回复到Detached孤立状态。

6. 校验DataSet中的数据

DataColumn列级约束

ReadOnly

AllowDBNull

MaxLength

Unique

DataTable表级约束

UniqueConstraints

Primarykey

ForeignkeyConstraints

7. DataTable对象编程

7.1创建DataTable对象

DataTable tbl= new DataTable(“TableName”);

7.2将DataTable添加到DataSet对象的Table集合中

ds.Tables.Add(tbl);

7.3为DataTable添加列

DataColumn col = tbl.Columns.Add(“CustomerID”);

7.4指定DataColumn的数据类型

DataColumn col = tbl.Columns.Add(“CustomerID”,typeof(int));

7.5添加主键

tbl.PrimaryKey=new DataColumn[]{tbl.Columns["OrderID"],tbl.Columns["ProductID"]};

7.6添加其他约束

col.AllowDBNull=false;

col.MaxLength=5;

col.Unique=true;

tbl.Constraints.Add(new UniqueConstraint(cols));

7.7处理自动增量

SqlConnection con = new SqlConnection("server=.;uid=sa;pwd=;database=pubs");

con.Open();

DataSet ds= new DataSet();

DataTable tbl = new DataTable("table1");

DataColumn colid=tbl.Columns.Add("id",typeof(int));

DataColumn colage=tbl.Columns.Add("age",typeof(int));

colid.AutoIncrement=true;

colid.AutoIncrementSeed=1;

colid.AutoIncrementStep=1;

ds.Tables.Add(tbl);

dataGrid1.DataSource=ds.Tables[0].DefaultView;

8. 修改DataTable内容

8.1添加新的DataRow

DataRow row = ds.Tables[0].NewRow;

Row[0]=”new Value”

Ds.tables[0].Rows.Add(row);

8.2修改当前行

方法一:row[“CompanyName”]=”NewCompanyName”;

8.3处理DataRow空值

If(row.IsNull(“ColumnName”)){

row[“ColumnName”]=DBNull.Value;

}

注意:当值为null时使用System.DBNull类的Value属性为DataRow赋值

8.4删除DataRow

row.Delete();

注意:这实际上是将该行挂起

8.5清除DataRow

DataRow dr = ds.Tables[0].Rows[1];

ds.Tables[0].Rows.Remove(dr);

Tbl.clear();//清除所有的记录

ds.Clear();//清除ds所有table中的数据

DataSet对象的属性

Tables

DataSet对象的方法

AcceptChanges() //接受DataSet里所有的挂起更改

Clear()

HasChanges()

DataTable对象的属性

Columns

Rows

DataSet

DefaultView

PrimaryKey

TableName

DataTable对象的方法

AcceptChanges()

Clear()

NewRow

DataColumn对象的属性

AllowDBNull boolean

AutoIncrement Boolean

AutoIncrementSeed

AutoIncrementStep

ColumnName

DataType

DefaultValue

MaxLength

ReadOnly

Table

Unique

DataRow对象的属性

Table

DataRow对象的方法

AcceptChanges()

Delete()

isNull()

DataRelation对象

作用:创建表之间的关系

说明:DataRelation与ForeignKeyConstraints都是设置表关系的。区别如下:

1.DataRelation对象属于DataSet对象

2.ForeignKeyConstraints对象属于DataTable对象

3.在创建DataRelation时会自动创建ForeignKeyConstraints,而且如果ForeignKeyConstraints对象如果在创建DataRelation之前已经创建好的话,DataRelation对象就直接引用ForeignKeyConstraints对象。

1. 创建DataRelation对象

DataRelation rel= new DataRelation("约束名称",主表.主键,从表.外键);

DataRelation rel= new DataRelation("CustomerOrders",

ds.Tables["Customers"].Columns["CustomersID"],

ds.Tables["Orders"].Columns["CustomersID"]);

2. DataRow对象的GetChildRows方法

该方法用于查找主表中主键对应的从表的外键行

foreach(DataRow rowCustomer in ds.tables[“Customers”].Rows)

{

foreach(DataRow rowOrder in rowCustomer.GetChildRows(“RelationName”))

Console.WriteLine(rowOrder[“OrderDate”]);

}

3. DataRow对象的GetParentRow方法

该方法用于查找从表的外键对应主表中的主键行

foreach(DataRow rowOrder in ds.tables[“Orders”].Rows)

{

DataRow Customer = rowOrder.GetParentRow(“RelationName”)

Console.WriteLine(Customer [“CompanyName”]);

}

DataTable对象的排序,搜索,筛选。

1. tbl.Rows.Find方法

该方法接受一个包含要查找行的主键值的对象,因为主键值是唯一的,所以Find方法只能返回一个DataRow对象。

Tbl.PrimaryKey = new DataColumn[ ] { tbl.columns[“CustomerID”] }

DataRow row = tbl.Rows.Find(“ALFKI”)

If (row==null){

Console.writeline(“row not found”);

}else{

Console.writeline(row[“CompanyName”]);

}

当主键是由表级主键构成的,应该这样处理。

Tbl.PrimaryKey = new DataColumn[ ] { tbl.columns[“CustomerID”], tbl.columns[“ProductID”]};

Object obj = new Object[]{10643,28}

DataRow row = tbl.Rows.Find(obj)

If (row==null){

Console.writeline(“row not found”);

}else{

Console.writeline(row[“CompanyName”]);

}

2. tbl.select 方法

该方法类似于sql语句中的where

DataTable tbl= new DataTable();

DataRow []aRows = tbl.Select("country='usa' and city='Seattle'")

foreach(DataRow row in aRows){

Consolw.wirteline(row["country"]);

}

3. 通配符% *

DataTable tbl= new DataTable();

DataRow []aRows = tbl.Select("country like ‘New %’ ")

foreach(DataRow row in aRows){

Consolw.wirteline(row["country"]);

}

4. 排序

DataTable tbl= new DataTable();

DataRow []aRows = tbl.Select("country like ‘New %’ ", “City desc”)

foreach(DataRow row in aRows){

Consolw.wirteline(row["country"]);

}

DataView对象

DataTable 对象的Select 方法是强大的,灵活的,但是他并不总是最佳的解决方案。它主要有两方面的局限性。其一,由于他接受动态搜索条件,所以它并不是很高效。其二,Windows 和 web 窗体都不支持绑定到Select方法的返回值(即一个DataRow数组),因此Ado.net引入的DataView对象。

DataView对象不维护自己的数据副本。当您通过DataView访问数据时,DataView将返回存储在相应的DataTable中的数据。

DataView可以用来筛选,排序,搜索DataTable中的内容,但是他们不是sql语句,不能使用DataView在两个DataTable对象之间使用jion查询。

不能使用DataView查询DataTable中的部分列,必须全部查询。

一个DataView只能访问一个DataTable。

1. DataView解决多DataTable查询问题

将表的列通过关系添加到子表中

Ds.Relations.Add(“CustomerOrders”,

ds.tables[“Customers”].Columns[“CustomerID”], ds.tables[“Orders”].Columns[“OrdersD”])

ds.Tables[“Orders”].Columns.add(

“CompanyName”, typeOf(string),

”parent(CustomerOrders).CompanyName”)

2. 使用DataView对象

DataTable tbl = new DataTable(“TableName”); // tableName是必须的

DataView vue;

Vue = new DataView();

Vue.Table=tbl;

// Vue = new DataView(tbl);

3. DataView对象的筛选,排序

DataViewRowState d;

DataView vue;

DataTable tbl;

d=DataViewRowState.ModifiedOriginal | DataViewRowState.Deleted ;

tbl = new DataTable(“TableName”);

// tableName是必须的,否则tbl对象没有表名称,无法绑定到datagrid控件,但是从DataSet中取出来的DataTable可以没有表名称,因为他有默认的表名称table0 table1 等等。

Vue = new DataView();

Vue.RowFilter=”Country=’USA’”;

Vue.Sort=”City Desc”;

Vue.RowStateFilder=d;

// Vue = new DataView(tbl ,”Country=’USA’ ”,”City desc”,d);

4. 使用DataRowView 对象

DataTable tbl = new DataTable(“customers”)

DataView vue = new DataView(tbl);

DataRowView vRow=vue[0];

Console.wirteline(row[“CompanyName”]);

DataRow dRow = vRow.row;

5. 通过DataView查看所有可用行

for(int i=0;i<vue.Count;i++){

DataRowView row=vue[i];

Console.Writeline(row[“CompanyName”]);

}

IEnumerator obj = vue.GetEnumerator();

While (obj.Movenext()){

Row= (DataRowView)obj.Current;

Console.Writeline(row[“CompanyName”]);

}

6. Find方法

一旦设置了DataView对象的Sort属性,就可以调用它的Find方法,Find方法根据Sort属性中所指定的列来查找。但是他并不返回DataRow或DataRowView对象,而是返回一个整型值,该值对应被查找行的索引。如果不能查找到,返回-1

DataView vue = new DataView(tbl);

Vue.sort=”CompanyName”;

Int intindex=vue.Find(“Fran Wilson”);

If (intindex==-1){

Console.writeline(“Row not found”);

}else{

Console.writeline(vue[intindex][“CompanyName”]);

}

7. FindRows方法

该方法返回DataRowView对象数组

DataRowView [] aRows = vue.FindRows(“Spain”);

If(aRows.Length==0){

Console.writeLine(“No row found”);

}else{

Foreach(DataRowView row in aRows){

Console.writeLine(row[“city”]);

}

}

//通过DataTable 添加新行

private void button1_Click(object sender, System.EventArgs e)

{

conn=new SqlConnection("server=.;uid=sa;pwd=;database=ggjxc");

adap= new SqlDataAdapter("select * from 用户表",conn);

ds=new DataSet();

adap.Fill(ds,"用户表");

DataRow drow=ds.Tables[0].NewRow();

drow["用户名"]="username";

drow["密码"]="username";

drow["姓名"]="username";

tbl.Rows.Add(drow);

dataGrid1.DataSource=ds.Tables["用户表"].DefaultView;

}

//通过DataView修改一行

private void button1_Click(object sender, System.EventArgs e)

{

conn=new SqlConnection("server=.;uid=sa;pwd=;database=ggjxc");

adap= new SqlDataAdapter("select * from 用户表",conn);

ds=new DataSet();

adap.Fill(ds,"用户表");

DataView vue=new DataView(ds.Tables["用户表"]);

vue.Sort="用户名";

int intindex=vue.Find("sjx");

DataRowView row=vue[intindex];

row.BeginEdit();

row["用户名"]="new username";

row.EndEdit();

dataGrid1.DataSource=ds.Tables["用户表"].DefaultView;

}

//删除一行

Row.delete();

8. RowFilter属性

该属性能够过滤DataView中的行

private void button1_Click(object sender, System.EventArgs e)

{

conn=new SqlConnection("server=.;uid=sa;pwd=;database=ggjxc");

adap= new SqlDataAdapter("select * from 用户表",conn);

ds=new DataSet();

adap.Fill(ds,"用户表");

DataView vue=new DataView(ds.Tables["用户表"]);

vue.RowFilter="用户编号>1";

dataGrid1.DataSource=vue;

}

DataAdapter对象的更新逻辑

private SqlConnection conn;

private SqlDataAdapter adap;

private DataSet ds;

private SqlParameter sqlpara;

private void button1_Click(object sender, System.EventArgs e)

{

conn=new SqlConnection("server=.;uid=sa;pwd=;database=ggjxc");

adap= new SqlDataAdapter("select * from 用户表",conn);

ds=new DataSet();

adap.Fill(ds,"用户表");

dataGrid1.DataSource=ds.Tables[0].DefaultView;

}

private void button3_Click(object sender, System.EventArgs e)

{

string sql="update 用户表 set 密码=@pass where 用户名=@username";

adap.UpdateCommand=new SqlCommand(sql,conn);

sqlpara=adap.UpdateCommand.Parameters.Add("@username",SqlDbType.VarChar);

sqlpara.SourceColumn="用户名";

sqlpara.SourceVersion =DataRowVersion.Current ;

sqlpara=adap.UpdateCommand.Parameters.Add("@pass",SqlDbType.VarChar);

sqlpara.SourceColumn ="密码";

sqlpara.SourceVersion =DataRowVersion.Current ;

if (ds.HasChanges()){

adap.Update(ds,"用户表");

// Update delete insert select 与要执行的sql语句和DataGrid的行状态有关

//实际上是找到满足行状态的行来执行sql语句如:

//

string sql="delete from users where username=@username";

adap.DeleteCommand = new SqlCommand(sql,conn);

parm = adap.DeleteCommand.Parameters.Add("@username",SqlDbType.VarChar);

parm.SourceColumn="username";

parm.SourceVersion=DataRowVersion.Original;

ds.Tables[0].Rows[dataGrid1.CurrentRowIndex].Delete();//设置行状态

adap.Update(ds,"users");

//如果行状态没有变化,都是DataRowVersion.Original 增删改查都不会成功

}

}

posted @ 2011-08-25 17:54  DebugLZQ  阅读(234)  评论(0编辑  收藏  举报