一、数据源的连接
1、连接到数据源
ADO.NET通过SqlConnection类建立与SQL Server数据库的连接,例如:
string connString = “SERVER=…;DATABASE=…;UID=…;PWD=…”;
SqlConnection conn = new SqlConnection(connString);
conn.Open();
…
conn.Close();
2、连接字符串
连接字符串一般由键值对组成,之间以分号分隔,且属性名不去分大小写,连接字符串中包含的典型信息包括:数据库名称、服务器位置以及用户凭据,也可能包含一些运行信息,如超时时间、连接池设置等。
连接字符串一般存储在web.config文件中的专用区段<connectionStrings>,该区段的信息会被透明加密,例如:
<connectionStrings>
<add name=”NWind” c onnectionString=”SERVER=…;DATABASE=…;UID=…;PWD=...;” />
</connectionString>
web.config文件中相应区段定义的所有连接字符串都会被加载到ConfigurationManager.ConnectionStrings集合中。例如:
string connString = ConfigurationManager.ConnectionStrings[“NWind”].ConnectionString;
SqlConnection conn = new SqlConnection(connString);
3、连接池
与数据库进行连接是开销很高的操作,需要与数据库进行往返交互,因此应用程序频繁的数据库访问会因为每次的连接变得非常低效。为解决这一问题,ADO.NET采用了连接池的机制。
当连接池被创建后,会创建多个连接对象并将它们添加到池中,随后按需添加连接,直至达到池的连接数上限。当应用程序通过SqlConnection建立连接请求时,它并不是真正与数据库建立往返的交互连接操作,而是通过对象池获得连接对象,只要连接池中有可用的连接对象就直接将其返回给应用程序,否则,连接池会创建新的连接对象并返回给应用程序。同理,当SqlConnection调用Close或Dispose方法释放连接时,它也并未真正与数据库断开连接,而只是将连接对象返还给连接池(将其标记为可用)。
二、命令的执行
1、SqlCommand执行命令
1)命令类型
SqlConnection的CommandText属性用于获取或设置执行的语句或存储过程的名称,而SqlCommand的CommandType属性决定了执行命令的种类,其可能值为:
- Text:默认设置,指出要执行Transact-SQL。
- StoredProcedure:指出要执行存储过程。
- TableDirect:OLE DB程序支持该功能。
2)命令参数
SQL Server的.NET提供程序能够通过名称标识参数,只需要为其添加@符号前缀即可。例如如下SQL语句:
SELECT * FROM employees WHERE employed=@employid;
我们可以用如下方式添加参数:
SqlParameter parm = new Sqlparameter();
parm.ParameterName = “@employid”;
parm.DbType = DbType.Int32;
parm.Direction = ParameterDirection.Input;
parm.Value = value;
cmd.Parameters.Add(parm);
3)命令的同步执行
有四种同步执行命令的方法,如下:
- ExecuteNonQuery方法通常用来执行更新操作(如UPDATE、INSERT和DELETE语句)。
- ExecuteReader方法通常执行查询命令,返回数据读取器SqlDataReader类的实例。
- ExecuteSclar方法用于执行查询,返回结果值第一行第一列的值,其它数据会被丢弃,因此常用于执行SELECT COUNT语句或那些获取合计值的语句。
- ExecuteXmlReader方法用于执行返回XML数据的查询,并生成XmlReader对象。
4)数据读取器——SqlDataReader
数据读取器用于对生成的结果集进行遍历。但应记住一点,数据读取器要在连接的状态下操作。例如:
using (SqlConnection conn = new SqlConnection(connString)
{
string cmdText = “SELECT * FROM customers”;
SqlCommand cmd = new SqlCommand(cmdText, conn);
cmd.Connection.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
Customerlist.Items.Add(reader[“companyname”].ToString());
reader.Close();
}
5)命令的异步执行
为启用异步命令,需要将连接字符串的Async属性设置为true,我们可以通过三种方式构建异步执行的命令:非阻塞法、轮询法和回调法。
非阻塞法:
IAsyncResult iar = cmd.BeginExecuteReader();
// do something else meanwhile
…
SqlDataReader reader = cmd.EndExecuteReader(iar);
这里BeginExecuteReader是非阻塞操作,启用该操作后可以继续执行其后不相关的方法,而EndExecuteReader是阻塞操作,用于同步程序的剩余部分,直到正在执行的命令终止。
轮询法:
IAsyncResult iar = cmd.BeginExecuteReader();
do
{
// Do something here
} while (!iar.IsCompleted);
SqlDataReader reader = cmd.EndExecuteReader(iar);
回调法:
IAsyncResult ar = cmd.BeginExecuteReader(new AsyncCallback(ProcessData), cmd);
public void ProcessData(IAsyncResult ar)
{
SqlCommand cmd = (SqlCommand)ar.AsyncState;
SqlDataReader reader = cmd.EndExecuteReader(ar);
…
}
2、数据适配器执行命令
SqlDataAdapter是数据容器和数据源之间的桥接器,它能够将数据源的数据填充到数据容器,也能将数据容器中的数据提交给特定的数据源。
在数据容器中,DataSet对应于内存版本的数据库,DataTable对应于内存版本的表,DataView用于创建视图,DataRelation用于建立表之间的关系。它们共同构成了内存的数据库模型。
1)执行Fill操作
数据适配器对象使用Fill方法将数据源的数据填充到数据容器中。
Fill操作依赖SelectCommand属性,并构建于SqlCommand和SqlDataReader之上,它在内部使用SelectCommand属性对应的SqlCommand对象进行查询,使用SqlDataReader遍历所有记录,并填充到数据容器中。
using (SqlConnection conn = new SqlConnection(connString))
{
SqlDataAdapter adapter = new SqlDataAdapter();
DataSet ds = new DataSet();
adapter.SelectCommand = new SqlCommand(queryString, conn);
adapter.Fill(ds);
}
2)执行Update操作
要将客户端的数据提交给服务器,可以使用数据适配器的Update方法。例如:
Update操作依赖InsertCommand、UpdateCommand以及DeleteCommand属性,当调用Update方法时,DataAdapter将分析已作出的更改并执行相应的命令(INSERT、UPDATE或DELETE),当DataAdapter根据DataRow的RowState属性判断每一行是否有更新,如果有更新它将使用InsertCommand、UpdateCommand或DeleteCommand属性来执行更改。
SqlDataAdapter adapter = new SqlDataAdapter(
“SELECT CategoryID, CategoryName FROM Categories”, conn);
dataAdapter.UpdateCommand = new SqlCommand(
“UPDATE Categories SET CategoryName = @CategoryName
WHERE CategoryID = @CategoryID”, conn);
dataAdapter.UpdateCommand.Parameters.Add(“@CategoryName”,
SqlDbType.NVarChar, 15, “CategoryName”);
SqlParameter parameter = dataAdpater.UpdateCommand.Parameters.Add(
"@CategoryID", SqlDbType.Int);
parameter.SourceColumn = "CategoryID";
parameter.SourceVersion = DataRowVersion.Original;
DataRow row = dataSet.Tables["Categories"].Rows[0];
row ["CategoryName"] = "New Category";
dataAdpater.Update(dataSet, "Categories");
其中SqlParameter的SourceColumn属性用于绑定DateSet中的列。
3)表映射原理
Fill方法可以为生成的结果集命名,例如:
adapter.Fill(ds, “MyTable”);
第二个参数指明第一个结果集命名为MyTable,其它的结果集依次命名MyTable1、MyTable2等。
TableMappings属性用于建立结果集名到内存表之间的映射,例如:
DataSet ds = new DataSet();
adapter.TableMappings.Add(“MyTable”, “Employees”);
adapter.TableMappings.Add(“MyTable1”, “Products”);
adapter.TableMappings.Add(“MyTable2”, “Orders”);
adapter.Fill(ds, “MyTable”);
三、数据绑定
数据绑定是从固定源(数据源对象或数据源控件)获取数据并将其关联到服务器控件属性的过程。
1、数据源对象
在ASP.NET中,任何暴露IEnumerable接口的对象都是有效的可绑定数据源。具体来说,我们可以将Web控件绑定到以下类上:
- ADO.NET容器类(如DataSet、DataTable和DataView)
- 数据读取器
- 自定义的集合、字典和数组
2、数据源控件
数据源控件是一种专门用于与数据绑定控件交互的服务器控件,数据绑定控件通过调用数据源控件类的方法与数据源控件交互。
常用的数据源控件有SqlDataSource、ObjectDatasource、LinkDataSource和SiteMapDataSource等。
3、数据绑定控件
数据绑定控件是带有数据绑定相关属性的服务器控件。数据绑定相关属性有:
- DataSource属性使我们能够指定控件要连接的数据源对象。
- DataSourceID属性用于设置数据源组件的ID。
- DataMember属性用于在DataSource属性包含多个数据值时设置具体的数据集。
- DataTextField属性一般用于列表控件,用于指定将数据源中的哪个字段绑定到控件各项的ListItem.Text属性。
- DataValueField属性同DataTextField,用于指明绑定到控件的ListItem.Value属性。
- AppendDataBoundItems属性用来指明数据绑定项是追加到控件现有内容中,还是将现有内容改写。
- DataKeyField属性指定由DataSource属性指示的数据源中的键字段。
ASP.NET主要有两大类数据绑定控件:列表控件和迭代控件。列表控件有DropDownList控件、CheckBoxList控件、RadioButtonList控件和ListBox控件等;迭代控件有Repeater控件、DataList控件和DataGrid控件等。
4、数据绑定表达式
数据绑定表达式是由<%…%>包裹的可执行代码,以#号作为前缀。数据绑定表达式会在DataBind被调用后计算。
我们一般使用数据绑定表达式在服务器控件的起始标签内设置属性值。例如:
<asp:label runat=”server” Text=’<%# DateTime.Now %>’ />
注意,如果要对表达式用引号,应选择单引号。