首先 Refrences 加入 Microsoft.Practices.EnterpriseLibrary.Data
using directive
using Microsoft.Practices.EnterpriseLibrary.Data;在不使用 LINQ 和 Entity Framework 的狀況下,如果要將資料庫裡的資料轉變成為強型別的物件
1. 在未使用 Enterprise Library 之前原本的做法
public List<Customer> FindCustById1(String connName, String id) { String sql = @"SELECT * FROM CUSTOMERS WHERE CUSTOMERID = :ID"; String connString = ConfigurationManager.ConnectionStrings[connName].ConnectionString; using (OracleConnection connection = new OracleConnection(connString)) using (OracleCommand cmd = new OracleCommand(sql, connection)) { connection.Open(); cmd.Parameters.Add("ID", id); List<Customer> data = new List<Customer>(); using (OracleDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection)) { while (reader.Read()) { Customer item = new Customer(); item.CustomerId = reader["CUSTOMERID"] == DBNull.Value ? "" : reader["CUSTOMERID"].ToString(); item.CompanyName = reader["COMPANYNAME"] == DBNull.Value ? "" : reader["COMPANYNAME"].ToString(); item.Fax = reader["FAX"] == DBNull.Value ? "" : reader["FAX"].ToString(); item.Address = reader["ADDRESS"] == DBNull.Value ? "" : reader["ADDRESS"].ToString() data.Add(item); } } return data; } }2. 使用 Enterprise Library,主要精簡了取 Connection 和 物件換的部分,將 Coonection 的建立和關閉封裝在 Database 物件內, 並利用反射將 reader 取得的資料放入 Customer 內
public List<Customer> FindCustById2(String connName, String id) { String sql = @"SELECT * FROM CUSTOMERS WHERE CUSTOMERID = :ID"; Database db = DatabaseFactory.CreateDatabase(connName); using (DbCommand cmd = db.GetSqlStringCommand(sql)) { db.AddInParameter(cmd, "ID", DbType.String, id); List<Customer> data = new List<Customer>(); using (IDataReader reader = db.ExecuteReader(cmd)) { while (reader.Read()) { Customer item = MapBuilder<Customer>.BuildAllProperties().MapRow(reader); data.Add(item); } } return data; } }3. 使用 Enterprise Library 進階版, 更進一步的將 reader 轉成物件的部分簡化了, 但是要多寫一個 class, C# 目前(2013年)似乎無法用匿名的方式 implements interface
public List<Customer> FindCustById3(String connName, String id) { String sql = @"SELECT * FROM CUSTOMERS WHERE CUSTOMERID = :ID"; Database db = DatabaseFactory.CreateDatabase(connName); DataAccessor<Customer> accessor = db.CreateSqlStringAccessor<Customer>(sql, new MyParameterMapper()); IEnumerable<Customer> result = accessor.Execute(id); return new List<Customer>(result); } class MyParameterMapper : IParameterMapper { public void AssignParameters(DbCommand command, object[] parameterValues) { DbParameter parameter = command.CreateParameter(); parameter.ParameterName = ":ID"; parameter.Value = parameterValues[0]; command.Parameters.Add(parameter); } }Enterprise Library 的 Database 物件感覺跟 Spring 的 JdbcTemplate 有點類似, 兩者都將 connection 的開關封裝起來, 並可自定 RowMapper 物件, 建立轉換的規則
使用 Enterprise Library 查詢 Table 內全部資料, 在沒有查詢條件的狀況下程式碼更精簡了
public List<Customer> FindAllCust(String connectiopnName) { String sql = @"SELECT * FROM CUSTOMERS"; Database db = DatabaseFactory.CreateDatabase(connectiopnName); IEnumerable<Customer> result = db.ExecuteSqlStringAccessor<Customer>(sql); return new List<Customer>(result); }總結 : 使用 Enterprise Library 優點
1.簡化存取資料庫的程式碼
2.封裝 connction 開關動作,避免忘記關閉的情形
3.將 conneection 物件包裹起來, 避免程式碼和特定資料庫的 connection 實作產生依賴, 在使用標準的 ANSI SQL 情形下, 只要改改 config 就可以達到抽換不同種類資料庫的目標
Customer.cs
using System; namespace TestEnterpriseLibrary { class Customer { public String CustomerId { get; set; } public String CompanyName { get; set; } public String Fax { get; set; } public String Address { get; set; } } }App.config
<?xml version="1.0" encoding="utf-8"?> <configuration> <connStrings> <add name="testdb" connString="Data Source=test;User Id=testdb;Password=testdb;" providerName="Oracle.DataAccess.Client" /> </connStrings> </configuration>
0 comments:
Post a Comment