Enterprise Library v5.0 -- Data Access Application Block 开发向导(3)
微软企业库 Enterprise Library 5.0 正式发布!!!
Enterprise Library 5.0 开发向导- 简介(1)
Enterprise Library v5.0 -- Data Access Application Block 开发向导(2)
检索数据对象
现代程序开发都关注“数据对象”,使用数据传输对象(DTO)在应用程序层间传递数据,使用ORM(Object/Relations Mapping)实现数据访问层,或者充分利用客户端数据访问技术,如LINQ等等。
DAAB提供了使用SQL语句或存储过程检索数据的功能,返回的数据实现了IEnumerable接口的对象序列。
关于Accessors
DAAB数据访问块提供了2个核心类来执行这一查询:SprocAccessor和SqlStringAccessor。你可以使用Database 类的ExecuteSprocAccessor和ExecuteSqlStringAccessor方法,在一个方法中创建和执行这些Accessors。
Accessors使用2个其他的对象来管理你想传递给accessor的参数,并将从数据库返回的数据行映射为对象属性,然后返回给客户端代码。下图演示了整个流程。
如果你不指定参数mapper,accessor将自动使用默认的mapper来解析参数,但是这一特性仅仅适用于SQL Server或Oracle数据库的存储过程。当你使用SQL语句或者其他数据库时,你必须知道定制的参数mapper,负责解析参数。
如果你只指定输出的mapper,DAAB将使用默认的映射构造类,映射返回的数据列到创建的对象属性。此外,你也可以创建定制的映射,匹配数据列和对象属性。
创建并执行Accessor
下面的代码演示如何使用accessor执行一个存储过程,并操作返回的对象序列。你必须指定返回数据的对象类型。在本示例中是一个简单的Product类,有三个属性:ID、Name和Description。
// Create an object array and populate it with the required parameter values
object[] params = new object[] { "%bike%" };
// Create and execute a sproc accessor that uses the default
// parameter and output mappings.
var productData = defaultDB.ExecuteSprocAccessor<Product>("GetProductList",
params);
// Perform a client‐side query on the returned data. Be aware that
// the orderby and filtering is happening on the client, not in the database.
var results = from productItem in productData
where productItem.Description != null
orderby productItem.Name
select new { productItem.Name, productItem.Description };
// Display the results
foreach (var item in results)
{
Console.WriteLine("Product Name: {0}", item.Name);
Console.WriteLine("Description: {0}", item.Description);
Console.WriteLine();
}
使用LINQ访问Accessor返回的数据序列,删除description为空的数据,并按name排序,接着创建一个新的对象序列,包括Name和Description属性。
检索XML数据
几年前,XML是非常酷的新技术,将掌管未来世界和改变我们思考数据的方法。在很多情况下,从关系型数据库中检索XML数据是非常有用的,DAAB支持这一功能。
DAAB提供了检索XML数据的ExecuteXmlReader方法,接收包含FOR XML的SQL语句,向数据库执行SQL语句,返回结果为XmlReader。你可遍历返回的XML元素或使用.NET 框架支持的XML类。然而,SQLXML仅限于Microsoft SQL Server数据库。
static SqlDatabase sqlServerDB = null;
// Resolve a SqlDatabase object from the container using the default database.
sqlServerDB = EnterpriseLibraryContainer.Current.GetInstance<Database>() as SqlDatabase;
// Specify a SQL query that returns XML data
string xmlQuery = "SELECT * FROM OrderList WHERE State = @state FOR XML AUTO";
// Create a suitable command type and add the required parameter
// NB: ExecuteXmlReader is only available for SQL Server databases
using (DbCommand xmlCmd = sqlServerDB.GetSqlStringCommand(xmlQuery))
{
xmlCmd.Parameters.Add(new SqlParameter("state", "Colorado"));
using (XmlReader reader = sqlServerDB.ExecuteXmlReader(xmlCmd))
{
while (!reader.EOF) // Iterate through the elements in the XmlReader
{
if (reader.IsStartElement())
{
Console.WriteLine(reader.ReadOuterXml());
}
}
}
}
上述代码演示了使用ExecuteXmlReader方法,从XmlReader检索返回的XML数据。需要注意的是,默认情况下,返回结果为XML数据块,并不是一个有效的XML文档。
使用上述代码查询SQL Server数据库,按FOR XML AUTO查询,返回默认格式的XML数据,数据集中每一列表示为XML属性,如下所示。
<OrderList Id="1" Status="DRAFT" CreatedOn="2009‐02‐01T11:12:06" Name="Adjustable
Race" LastName="Abbas" FirstName="Syed" ShipStreet="123 Elm Street" ShipCity="Denver"
ShipZipCode="12345" ShippingOption="Two‐day shipping" State="Colorado" />
<OrderList Id="2" Status="DRAFT" CreatedOn="2009‐02‐03T01:12:06" Name="All‐Purpose
Bike Stand" LastName="Abel" FirstName="Catherine" ShipStreet="321 Cedar Court"
ShipCity="Denver" ShipZipCode="12345" ShippingOption="One‐day shipping"
State="Colorado" />
检索单一结果
访问数据的一个常见需求是检索一个单一数据值。DAAB提供了ExecuteScalar方法实现这一需求。它执行了指定的查询,并以Object类型返回第一行/第一列的数值。这意味着,它比ExecuteReader方法提供更好的性能,因为不必创建DataReader对象和构造结果集返回给客户端。为了最大化效率,你应该使用查询返回一个单一值,或者单一行。
// Create a suitable command type for a SQL statement
// NB: For efficiency, aim to return only a single value or a single row.
using (DbCommand sqlCmd
= defaultDB.GetSqlStringCommand("SELECT [Name] FROM States"))
{
// Call the ExecuteScalar method of the command
Console.WriteLine("Result using a SQL statement: {0}",
defaultDB.ExecuteScalar(sqlCmd).ToString());
}
// Create a suitable command type for a stored procedure
// NB: For efficiency, aim to return only a single value or a single row.
using (DbCommand sprocCmd = defaultDB.GetStoredProcCommand("GetStatesList"))
{
// Call the ExecuteScalar method of the command
Console.WriteLine("Result using a stored procedure: {0}",
defaultDB.ExecuteScalar(sprocCmd).ToString());
}
更新数据
当使用UPDATE、DELETE、或者INSERT 语句时,可调用Database类的ExecuteNonQuery方法,执行数据更新操作。
和前面介绍的ExecuteReader方法一样,ExecuteNonQuery方法有一系列重载。你可以指定CommandType(默认为StoredProcedure)和SQL语句、存储过程的名称等等。你可传递对象实例数组,表示查询参数。此外,你也可传递Command对象,包含了你需要的任何参数,同时也提供了Begin和End版本的方法,用来异步执行更新操作。
string oldDescription = "Carries 4 bikes securely; steel construction, fits 2\" receiver hitch.";
string newDescription = "Bikes tend to fall off after a few miles.";
// Create command to execute the stored procedure and add the parameters.
DbCommand cmd = defaultDB.GetStoredProcCommand("UpdateProductsTable");
defaultDB.AddInParameter(cmd, "productID", DbType.Int32, 84);
defaultDB.AddInParameter(cmd, "description", DbType.String, newDescription);
// Execute the query and check if one row was updated.
if (defaultDB.ExecuteNonQuery(cmd) == 1)
{
// Update succeeded.
}
else
{
Console.WriteLine("ERROR: Could not update just one row.");
}
// Change the value of the second parameter
defaultDB.SetParameterValue(cmd, "description", oldDescription);
// Execute query and check if one row was updated
if (defaultDB.ExecuteNonQuery(cmd) == 1)
{
// Update succeeded.
}
else
{
Console.WriteLine("ERROR: Could not update just one row.");
}
操作DataSet数据集
DAAB支持检索DataSet数据集,同时也支持从DataSet更新原始的数据库记录。
你可以是ExecuteDataSet方法,获取一个新的DataSet对象实例,该DataSet对象包含有查询返回的数据表。DataSet中的数据表有默认的表名称,如Table、Table1和Table2等等。
如果你想将数据装载进一个现存的DataSet对象,你可以使用LoadDataSet方法,这样允许你指定名称或DataSet中的目标数据表,还可让你添加额外的数据表到一个现有的DataSet,或者更新DataSet中的特定表的内容。
DataSet productDataSet;
// Using a SQL statement and a parameter array.
productDataSet = db.ExecuteDataSet(CommandType.Text, "GetProductsByCategory",
new Object[] { "%bike%" });
// Using a stored procedure and a parameter array.
productDataSet = db.ExecuteDataSet("GetProductsByCategory",
new Object[] { "%bike%" });
// Using a stored procedure and a named parameter.
DbCommand cmd = db.GetStoredProcCommand("GetProductsByCategory");
db.AddInParameter(cmd, "CategoryID", DbType.Int32, 7);
productDataSet = db.ExecuteDataSet(cmd);