原文地址:http://blog.sina.com.cn/s/blog_94b91f620100xtwf.html
如何使用微软企业库对数据库的访问
1、摘要
数据访问应用程序块简化了许多公共的数据访问任务,例如用于显示的数据读取,通过应用程序层(application layers)来传递数据,及提交变更数据给数据库系统。它提供存储过程与内联SQL两种支持,将数据以对象序列的形式公开让客户端查询,也通过使用便利的类提供ADO.NET中最常使用的功能, 可以提高应用程序的开发效率。同时除了简化开发以外,它使得你可以创建一种provider独立的应用,可以很容易的更换不同的数据提供源。在大多数情况下,除非你在代码中指定了数据库类型,剩下的就是更改配置文件中的连接字符串配置节就可以了。不需要你修改代码中的sql查询和存储过程及其参数。模块也支持多个操作的事务,如果失败的话,可以回滚。
2、问题描述
在我们进行基于数据库应用程序开发中,模块也支持多个操作的事务,如果失败的话,可以回滚,防止了插入了脏数据、错误数据。模块还支持异步访问数据库(只要数据支持)。还可以返回客户端可以用LINQ查询的数据的序列对象形式。
3、解决步骤
第一步安装Enterprise Library 5.0(下载地址:
http://www.microsoft.com/downloads/details.aspx?FamilyId=bcb166f7-dd16-448b-a152-9845760d9b4c&displaylang=en) ,安装完成时会有弹出窗口提示是否安装源代码,我们可以选择安装下,来看看里面的具体体结构,这样更有利于我们了解和学习。
首先我们必须添加引用(dll在安装文件的目录中)
using System.Data;
using Microsoft.Practices.EnterpriseLibrary.Data;
下面列出一些模块常用的获取数据、更新数据方法,其中有一些和直接使用ADO.NET中的方法很相似:
方法 | 功能 |
ExecuteDataset,创建,加载,返回数据集 LoadDataSet,加载数据到一个已经存在的数据集 TransactionScope,支多项事务同时执行,一旦发生异常则会回滚所有操作 | 填充一个数据集,使用数据集更新数据库 |
ExecuteReader,创建,返回一个provider独立的DbDataReader实例 | 从数据库读取多行数据 |
ExecuteNonQuery,执行command,返回数据库受影响的行数,可以通过output返回多个值 ExecuteScalar,执行command,返回单个值第一行第一列的值 | 执行command数据库命令对象 |
ExecuteSproAccessor,使用存储过程返回一个客户端可以查询的序列对象 ExecuteSqlStringAccessor,使用SQL语句返回一个客户端可以查询的序列对象 | 以序列对象的形式返回数据 |
ExecuteXmlReader,返回xml格式的数据,xmlReader类型,这个只能用在SQL Server数据库,通过SqlDatabase类调用,Database类中没有这个方法。 | 获取xml格式数据(只能用在SQL Server数据库) |
GetStoredProcCommand,返回一个存储过程的数据库command对象 GetSqlStringCommand,返回一个SQL语句的数据库command对象 | 创建一个Command对象 |
AddInParameter,创建一个新的input参数,并且加入command的参数集合 AddOutParameter,创建一个新的output参数,并且加入command的参数集合 AddParameter,创建一个指定类型的参数,并且加入command的参数集合 GetParameterValue,以Object类型返回指定参数的值 SetParameterValue,给指定参数赋值 | 处理command的参数 |
CreateConnection,创建,返回当前数据库的连接,允许你通过这个链接初始化和管理数据库事务 | 处理数据库事务 |
下面我们通过案例来演示以上常用的方法的使用:
1、 首先我们来编辑配置文件:
在菜单栏中选定Blocks>Add Data Setting来添加数据库的类型和连接字符串
name | 由应用程序访问的数据库实例的逻辑名称。在节中,名称必须是唯一的。此属性是必须的。 |
providerName | 提供程序的名称。默认情况下,提供程序的名称定义在 Machine.config 文件中。providerName 名称必须是一个在 DBProviderFactory 类中指定的提供程序的名称。此属性是必须的。 |
connectionString | 可用于被选的提供程序的连接字符串,此属性是必须的。 |
首先我们实例化一个DataBase
private static Database db = DatabaseFactory.CreateDatabase("Test");
1. ExecuteDataset:创建,加载,返回数据集,ExecuteScalar返回单个值第一行第一列的值
string sql = "select * from [User]";
DbCommand com = db.GetSqlStringCommand(sql);
//执行并返回数据集
rptTest.DataSource = db.ExecuteDataSet(com).Tables[0];
rptTest.DataBind();
2 . LoadDataSet,加载数据到一个已经存在的数据集
private void LoadDataSet()
{
DataSet table;
string sql = "select * from [User]";
DbCommand com = db.GetSqlStringCommand(sql);
DbCommand com1 = db.GetSqlStringCommand(sql);
table = db.ExecuteDataSet(com1);
// 执行com 并将所得到得结果追加的数据集table中
db.LoadDataSet(com, table, "table");
rptTest.DataSource = table.Tables["table"];
rptTest.DataBind();
}
3.ExecuteReader,创建,返回一个provider独立的DbDataReader实例
private void ExecuteReader()
{
string sql = "select * from [User]";
DbCommand com = db.GetSqlStringCommand(sql);
IDataReader read = db.ExecuteReader(com);
Label1.Text=" <div class='left title'> 姓名</div>
<div class='right title'> 邮箱</div>
<div style='clear: both; width:200px'>";
while (read.Read())
{
//获取该列的所有信息
object[] values = new object[3];
read.GetValues(values);
Label1.Text += "<div class='left'>" + values[0].ToString() + "</div>"+ "<div class='left'>" + values[2].ToString() + "</div> ";
}
Label1.Text += "</div>";
read.Close();
}
4. ExecuteScalar,执行command,返回单个值第一行第一列的值
string sql = "select * from [User]";
DbCommand com = db.GetSqlStringCommand(sql);
bl.Text = string.Format("第一行第一列的数据:{0}", db.ExecuteScalar(com).ToString());
5. GetSqlStringCommand方法用于 SQL 文本命令
protected void Page_Load(object sender, EventArgs e)
{
select();
}
private void getSqlStringCommand(string sqlQuery)
{
//GetSqlStringCommand方法的使用
DbCommand com = db.GetSqlStringCommand(sqlQuery);
db.ExecuteNonQuery(com);
select();
}
//为了区别添加数据跟已有数据区分开来
private static int ID = 0;
//插入数据
protected void Insert_Click(object sender, EventArgs e)
{
getSqlStringCommand("insert[User] values('江苏迈瑞" + (ID++).ToString() +"'," + "'www.maxray.com','hr@maxray.cn') ");
}
//查询信息
private void select()
{
string sqlQuery = "select * from [User] ";
DbCommand com = db.GetSqlStringCommand(sqlQuery);
rptGetSqlStringCommand.DataSource = db.ExecuteDataSet(com).Tables[0];
rptGetSqlStringCommand.DataBind();
}
//删除信息
protected void bntDelete_Click(object sender, EventArgs e)
{
getSqlStringCommand("delete [User] where UserName='江苏迈瑞"
+ (ID--).ToString()+"'");
}
//更新数据
protected void update_Click(object sender, EventArgs e)
{
getSqlStringCommand("update [User]
set UserName='updata_江苏迈瑞'
where UserName='测试1' ");
}
6. GetStoredProcCommand方法用于执行存储过程命令
private void getStoredProcCommand()
{
//执行存储过程 (不带参数)
DbCommand com = db.GetStoredProcCommand("proc_list");
rptGetStoredProcCommand.DataSource = db.ExecuteDataSet(com).Tables[0];
rptGetStoredProcCommand.DataBind();
}
7.参数处理(存储过程和T-Sql中的参数)
1. Database中的GetStoredProcCommand方法用于执行存储过程命令。
2. Database中的GetSqlStringCommand方法用于 SQL 文本命令。
二个方法都返回一个DbCommand对象。
(1)sql语句中的参数处理
string sql = "select * from [User] where ID=@ID ";
DbCommand com=db.GetSqlStringCommand(sql);
//添加参数
db.AddInParameter(com, "@ID", DbType.Int32, 1);
rptTest.DataSource = db.ExecuteDataSet(com).Tables[0];
rptTest.DataBind();
(2)存储过程中的参数处理(参数以“proc_“为存储过程)
a)参数发现
//直接指定参数的值,在这里要注意参数出现的顺序应与存储过程中的顺序相同
。如果数据类型转换失败,则报出异常。
DbCommand com = db.GetStoredProcCommand("proc_Test",
"测试",
12);
db.ExecuteNonQuery(com);
b) 处理参数
AddInParameter,创建一个新的input参数,并且加入command的参数集合
AddOutParameter,创建一个新的output参数,并且加入command的参数集合
AddParameter,创建一个指定类型的参数,并且加入command的参数集合
GetParameterValue,以Object类型返回指定参数的值
private void GetStoredProcCommand()
{
DbCommand com = db.GetStoredProcCommand("proc_Login");
//设置指定参数的值、类型
db.AddInParameter(com, "@Psd", DbType.Int32, 12);
db.AddInParameter(com, "@UserName", DbType.String, "1212");
//获取数据库中的返回值
db.AddParameter(com, "@retrunvalue", DbType.String,ParameterDirection.ReturnValue, null, DataRowVersion.Current, null);
db.AddOutParameter(com, "@outputEmail", DbType.String, 20);
db.ExecuteNonQuery(com);
string Rvalue=com.Parameters["@retrunvalue"].Value.ToString();
string OEmail= com.Parameters["@outputEmail"].Value.ToString();
string GValue = db.GetParameterValue(com,"@name").ToString();
lblInfo.Text = "<div class='left title'> 返回的参数为</div> <br/>
<br/>GetParameterValue=" + GValue +
"<br /> AddOutParameter=" + OEmail +
"<br /> ReturnValue=" + Rvalue;
}
存储过程
ALTER proc [dbo].[proc_Login]
@Psd varchar(50),
@UserName varchar(50) ,
@outputEmail varchar(50) output
AS
BEGIN
set @outputEmail=( SELECT Email FROM [User] WHERE Psd = @Psd and UserName=@UserName)
return @@rowcount
END
8. ExecuteSproAccessor,使用存储过程返回一个客户端可以查询的序列对象
private void executeSproAccessor()
{
var student = db.ExecuteSprocAccessor<Student>("proc_Test",
"江",
1);
Student[] std = student.ToArray();
for (int i = 0; i < std.Count<Student>(); i++)
{
Label1.Text += std[i].id + " " + std[i].email + " " +
std[i].psd + " " + std[i].username + "<br/>";
}
}
9. ExecuteSqlStringAccessor,使用SQL语句返回一个客户端可以查询的序列对象
private void executeSproAccessor()
{
var student = db.ExecuteSqlStringAccessor<Student>(
"select * from [User]");
Student[] std = student.ToArray();
for (int i = 0; i < std.Count<Student>(); i++)
{
Label1.Text += std[i].id + " " + std[i].email + " " +
std[i].psd + " " + std[i].username + "<br/>";
}
}
10. ExecuteXmlReader,返回xml格式的数据,xmlReader类型,这个只能用在SQL Server数据库,通过SqlDatabase类调用,Database类中没有这个方法。
private void executeXmlReader ()
{
string sql = "SELECT * FROM [User] FOR XML AUTO";
Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase
sqlDB=(Microsoft.Practices.EnterpriseLibrary.Data.Sql.
SqlDatabase)db;
DbCommand cmd = sqlDB.GetSqlStringCommand(sql);
var reader = sqlDB.ExecuteXmlReader(cmd);
string xml= "<?xml version='1.0' encoding='utf-8' ?><root>";
while (!reader.EOF)
{
if ((reader.IsStartElement()))
{
xml += reader.ReadOuterXml();
}
}
xml += "<root>";
Response.Write(xml);
Response.End();
}
11. TransactionScope支多项事务同时执行,一旦发生异常则会回滚所有操作
protected void TransactionScope()
{
// insert操作会发生失败,同时会回滚delete事件
string sqlInsert = "insert [User] values('12','江苏迈瑞')";
string sqlDelete = "delete [User] where ID=8";
try
{
using (TransactionScope sp =
new TransactionScope(TransactionScopeOption.RequiresNew))
{
db.ExecuteNonQuery(CommandType.Text, sqlDelete);
db.ExecuteNonQuery(CommandType.Text, sqlInsert);
sp.Complete();
}
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
}
}
4、参考资料
微软企业库5.0学习笔记(三十四)数据访问模块 各种获取数据的方式
5、作者
成向阳 chengxiangyang@maxray.cn 研发部 web组
陈 平 ChenPing@maxray.cn 研发部 web组
6、版本
V0.1 C 2011-11-15
V1.0 P 2011-11-16
7、标签
公司:江苏迈瑞信息技术有限公司
地址:江苏扬州市广陵区信息产业服务基地1期3号楼2楼
网址:http://www.maxray.cn
邮箱:development@maxray.cn
电话:0514-89886226-802