Enterprise LibraryV1.0-数据应用程序块
1、简介
数据应用程序块把我们从大量的机械的数据库访问代码中解放出来,同时给我们带来了在多个数据库甚至多个不同类型的数据库的中无缝切换的可能。
数据应用程序块的类继承层次非常简单,这里就不做详细介绍了(向看此文的朋友问个问题:为什么Vs.net2003的类视图窗口中很多类都不显示?)。
我们在我前面的配置应用程序块中提到过,要读取我们的自定义配置数据,首先要写一个配置数据类,数据应用程序块也不例外,这个类就是DatabaseSettings,其结构如下图:
从这个图里,我们可以看到DatabaseSettings主要包括3个集合类,DatabaseTypeData说明了配置的数据库类型,ConnectionStringData指明了每种数据库类型的连接串,InstanceData指明了当前的数据库实例。
2、使用说明
使用时分两步:先用配置控制台添加数据应用程序块,再在程序中写代码。
⑴用配置控制台添加数据应用程序块
①添加数据应用程序块,之后是分别设置应用程序要访问的数据库类型、每个类型的数据库即连接串和当前的默认数据库。
②添加应用程序要访问的数据库类型(Database Types),如SQL Server、Oracle、Sybase、Access等
③设置每个数据库的连接串。添加上相应的连接参数。
④设定默认的数据库及其连接串。
⑤设置完毕,保存。
⑵写数据访问代码
数据应用程序块支持我们常见的大部分功能:执行SQL文本,执行存储过程、启用事务、离线处理、批量更新等等,下面我们分别举例说明。
①执行SQL语句
Database db = DatabaseFactory.CreateDatabase();
string sql = "SELECT * FROM [AddressList]";
DBCommandWrapper cmdWrapper = db.GetSqlStringCommandWrapper(sql);
return db.ExecuteDataSet(cmdWrapper);
②执行存储过程
Database db = DatabaseFactory.CreateDatabase();
string sqlCommand = "GetUserById";
DBCommandWrapper cmd = db.GetStoredProcCommandWrapper(sqlCommand);
cmd.AddInParameter("@UserId", DbType.Int32, 1);
Literal1.Text = (string)db.ExecuteScalar(cmd);
③启用事务
Database db = DatabaseFactory.CreateDatabase();
string sqlCommand = "CreditAccount";
DBCommandWrapper creditCommandWrapper = db.GetStoredProcCommandWrapper(sqlCommand);
sqlCommand = "DebitAccount";
DBCommandWrapper debitCommandWrapper = db.GetStoredProcCommandWrapper(sqlCommand);
using (IDbConnection connection = db.GetConnection())//
{
connection.Open();
IDbTransaction transaction = connection.BeginTransaction();
try
{
db.ExecuteNonQuery(creditCommandWrapper, transaction);
db.ExecuteNonQuery(debitCommandWrapper, transaction);
transaction.Commit();
result = true;
}
catch
{
transaction.Rollback();
}
connection.Close();
return result;
}
④批量更新
Database db = DatabaseFactory.CreateDatabase();
DataSet productsDataSet = new DataSet();
string sqlCommand = "Select ProductID, ProductName, CategoryID, UnitPrice, LastUpdate From Products";
DBCommandWrapper dbCommandWrapper = db.GetSqlStringCommandWrapper(sqlCommand);
string productsTable = "Products";
db.LoadDataSet(dbCommandWrapper, productsDataSet, productsTable);
DataTable table = productsDataSet.Tables[productsTable];
DataRow addedRow = table.Rows.Add(new object[] {DBNull.Value, "New product", 11, 25});
table.Rows[0]["ProductName"] = "Modified product";
DBCommandWrapper insertCommandWrapper = db.GetStoredProcCommandWrapper("AddProduct");
insertCommandWrapper.AddInParameter("@ProductName", DbType.String, "ProductName", DataRowVersion.Current);
insertCommandWrapper.AddInParameter("@CategoryID", DbType.Int32, "CategoryID", DataRowVersion.Current);
insertCommandWrapper.AddInParameter("@UnitPrice", DbType.Currency, "UnitPrice", DataRowVersion.Current);
DBCommandWrapper deleteCommandWrapper = db.GetStoredProcCommandWrapper("DeleteProduct");
deleteCommandWrapper.AddInParameter("@ProductID", DbType.Int32, "ProductID", DataRowVersion.Current);
DBCommandWrapper updateCommandWrapper = db.GetStoredProcCommandWrapper("UpdateProduct");
updateCommandWrapper.AddInParameter("@ProductID", DbType.Int32, "ProductID", DataRowVersion.Current);
updateCommandWrapper.AddInParameter("@ProductName", DbType.String, "ProductName", DataRowVersion.Current);
updateCommandWrapper.AddInParameter("@LastUpdate", DbType.DateTime, "LastUpdate", DataRowVersion.Current);
int rowsAffected = db.UpdateDataSet(productsDataSet, "Products", insertCommandWrapper, updateCommandWrapper,
deleteCommandWrapper, UpdateBehavior.Standard);
这里的代码来源于Quick Start,这里需要注意的就是DataRowVersion.Current,批量更新时根据具体情况选择其值。同时ExecuteScalar、UpdateDataSet等方法重载好几个不同的方法原型,您可以根据具体情况选择。
⑶注意的问题
这里需要注意的就是在执行存储过程时,有两个获取IDbCommand对象的方法:
public abstract DBCommandWrapper GetStoredProcCommandWrapper(string storedProcedureName);
public abstract DBCommandWrapper GetStoredProcCommandWrapper(string storedProcedureName, params object[] parameterValues);
如果你要缓存参数,就用第二个方法,不缓存参数就用第一个方法(不知我说的对不对?),因为在准备IDbCommand对象时,有下面的语句,
if (command.IsFurtherPreparationNeeded())
{
parameterCache.FillParameters(command, ParameterToken);
}
这样,在用第二个方法时,会从缓存中取参数,当你多次调用同一存储过程时,可以考虑用用第二个方法,当然,如果有必要可以缓存执行的结果,性能更佳,这将用到缓存应用程序块。
还需要提一句,就是对于保存在配置文件中的数据库信息,我们也是可以加密的,方法与配置应用程序块的加密方式一致。可以看我关于配置应用程序块的使用方法说明。每个应用程序块的配置数据都是可以加密保存的。
有人已经制作了使用数据应用程序块的模板,比较不错:http://cstemplates.sourceforge.net