1.1. 概述:
使用NetTier模板產生的.net代碼,包括完整的資料層,使用的技術是微軟的
EnterpriseLibrary1.1版本,對應每張表都產生相對應的增刪改查函數和預存程序,在查詢中支
持多欄位查詢和翻頁。資料層為工廠模型,只要調用DataRepository 類即可擷取相應表的接
口執行個體,然後可以對改表進行操作了。對於多表關聯操作,在父表中可以擷取子集的查詢記
錄,儲存在IList 容器裡面,對於子表,提供父表的對象執行個體。對於資料庫的操作提供事務功
能。對於更加複雜的操作,直接提供EnterpriseLibrary的資料庫操作執行個體,直接進行操作。
特徵:
1、 產生vs.net工程和解決方案;
2、 整合EnterpriseLibrary1.1版本,對於資料庫連結可以直接使用EnterpriseLibrary的配置文
件;
3、 資料表和實體的映射關係是1:1的,每張表都有一個實體產生,在實體裡面對應了每個
欄位,實體類是序列化的,有trigger事件,支援枚舉類型的欄位;
4、 對於表和檢視窗產生的實體的操作包括:基本的CRUD操作:UPDATE, DELETE, INSERT,
SELECT ALL, PAGED SELECT, FIND;支援主鍵、外鍵、多表關聯、排序、分頁、sql
語句、視圖查詢;
5、 擷取強型別的資料集儲存在Ilist或者Vlist裡面,可以綁定到DataGrid、GridView或
者其他的頁面控制項中,支援表格排序;
6、 產生webservice 服務進行資料分發;
7、 建立預存程序指令碼,而且自動安裝到資料庫伺服器上面;
8、 產生nant的完整的build.xml 檔案,可以自動編譯、測試代碼,產生chm 格式的api
文檔;
9、 根據資料庫產生完整的資料驗證規則,包括一個管理規則的架構;
10、 每個表都有一個實體類,你可以在你的客戶代碼裡面繼承,然後增加自己的處理方
法;
11、 產生資料來源可以讓你你無需再去處理資料來源的問題了;
12、 建立全套的web admin使用者控制項,你可以對資料庫進行web管理;
13、 完整的nunit測試;
14、 完整的注釋,符合微軟的命名規則;
15、 nettiers 模板是免費開源的。
1.2. 架構結構:
資料邏輯包括客戶商務邏輯組件、資料介面邏輯組件(持久層邏輯),整個設計建築在el
上面。
下面以northwind資料庫的單表employee為例進行講解。
Employee資料表結構:
產生的OO 結構:
介面統一的調用DataRepository 擷取各功能塊的provider,然後進行單表的增刪改查操
作,如果需要更加複雜的商務邏輯,比如要用到事務來同時處理幾個表,那麼需要另外寫業務
邏輯代碼了,這些邏輯層代碼可以放在bl 層裡面。值得一提的是,現在在bl 層裡面產生的代
碼,只有最基本和通用的商務邏輯,只產生了單表資料的實體類VO、單表資料各欄位的處理
和資料集合的排序、檢索等處理。
EmployeesCollection
EmployeesCollectionBase
Employees
EmployeesBase EmployeesVO
在DataRepository 裡面擷取各功能模組的provider的方法是static 方法,得到的是各
個sqlprovider 的執行個體,而提供給外界使用的是其對應的抽象類別定義的方法。
執行個體的調用順序是:
:
DataRepository
:
SqlDataProvider
:
SqlEmployeesProviderBase
1: EmployeesProvider
2: GetAll
3: GetByEmployeeID
分析DataRepository.EmployeesProvider.GetAll()的操作:執行個體化的順序是
DataRespository 類裡面維護了一個全域的變數Current,這個Current實際上是
SqlDataProvider 的執行個體,而Current是DataProviderBase 類型,關係為:
DataProviderBase
SqlDataProvider
(from sqlclient)
在DataRepository 中擷取EmployeesProvider的時候,實際上是調用了
SqlDataProvider 裡面的方法EmployeesProvider(),new 了一個SqlEmployeesProvider 實
例,而這個執行個體中所有的方法的實現在SqlEmployeesProviderBase類中實現的,因為
SqlEmployeesProvider繼承了SqlEmployeesProviderBase類,這個類相當於是dao 層,直接進行
資料庫操作。
SqlEmployeesProviderBase
EmployeesProviderBase
(from base)
SqlEmployeesProvider
在產生各個sqlprovider 執行個體的時候,需要先執行個體化SqlDataProvider,這個用的是
Activator 類根據設定檔提供的這個類的名字產生的,nettier為了做到對不同資料庫的支
持,提供了一個設定檔nettiersconfigdata.config 和讀取這個設定檔的dll:
NetTiers.Configuration.dll。
Activator 類可以動態構造對象,有點像Java裡面的
Class.forName(ClassName).newInstance()語句,因為用Activator 類構造對象,其類名在
編譯時間可以不確定,所以可以用來做外掛程式的介面,做出Winamp 那種可以外加DLL 外掛程式的程式
來。
1.3. 調用介面的方法:
1.3.1. 擷取所有資料
擷取所有的Employee資料,按照LastName欄位進行排序:
using Northwind.DataAccessLayer;
// Get all the employee, sort it on the LastName and print them out
TList<Employees> employees = DataRepository.EmployeeProvider.GetAll();
employees.Sort(EmployeeColumns.LastName, ListSortDirection.Ascending);
foreach(Employee employee in employees)
{
Console.WriteLine("{1} {0}", employee.FirstName, employee.LastName);
}
1.3.2. 新增資料
建立一個新的employee 並且儲存
using Northwind.DataAccessLayer;
// Create a new record and save
Employee employee = new Employee();
employee.FirstName = "John";employee.LastName = "Doe";
employee.BirthDate = DateTime.Now;employee.Address = "10 , fake street";
employee.City = "Metroplolis";employee.Country = "USA";
employee.HireDate = DateTime.Now;
employee.HomePhone = "0123456789";
employee.Notes = "This is a fake employee";
employee.Title = "M";
employee.TitleOfCourtesy = "Dear";
employee.PostalCode = "5556";
employee.Region = "New-York";
DataRepository.EmployeeProvider.Insert(employee);
//look, new id already populated
Console.WriteLine("New Employee ID" + employee.EmployeeId);
1.3.3. 修改資料
按照下標擷取資料並且修改資料;
using Northwind.DataAccessLayer;
// Select by Index and Update
TList<Employees> employees =
DataRepository.EmployeeProvider.GetByLastName("Doe");
if (employees.Count == 1)
{
employees[0].Notes = "This is a modified fake employee";
DataRepository.EmployeeProvider.Save(employees[0]);
Console.Write(employees[0]);
}
1.3.4. 刪除資料
通過主鍵查詢資料並且刪除
using Northwind.DataAccessLayer;
// Select by primary key and Delete
// (Demonstrate that insert, update, delete methods can also take collection
as parameter)
Employee employee = SqlDataRepository.EmployeeProvider.GetByEmployeeID(13);
DataRepository.EmployeeProvider.Delete(employees);
1.3.5. 事務控制
事務控制執行個體,可以用事務控制插入、修改、刪除的操作,保證全部成功或者失敗復原;
using Northwind.DataAccessLayer;
// The SqlClient can work with transactions.
// Also show the Save method, wich encapsulate the use of Insert, Update and
Delete methods.
TransactionManager transaction = DataRepository.CreateTransaction();
transaction.BeginTransaction(/*IsolationLevel.ReadUncommited*/);
try
{
// Insert
Employee employee = new Employee();
employee.FirstName = "John";
employee.LastName = "Doe";
employee.BirthDate = DateTime.Now;
employee.Address = "10 , fake street";
employee.City = "Metroplolis";
employee.Country = "USA";
employee.HireDate = DateTime.Now;
employee.HomePhone = "0123456789";
mployee.Notes = "This is a fake employee";
employee.Title = "M";
employee.TitleOfCourtesy = "Doctor";
employee.PostalCode = "5556";
employee.Region = "New-York";
DataRepository.EmployeeProvider.Save(transaction, employee);
// modify the employee instance
employee.Notes = "This is a modified fake employee";
// Update
DataRepository.EmployeeProvider.Save(transaction, employee);
transaction.Commit();
Console.WriteLine("ok");
}
catch(Exception ex)
{
try { transaction.Rollback();} catch(){}
Console.WriteLine("nok : {0}", ex);
}
1.3.6. 關聯儲存
深度儲存,可以同時儲存父物件和子集
/*
DeepSave helper method can help you to save an object and its children in
one call.
*/
using Northwind.DataAccessLayer;
Order order = Order.CreateOrder("ALFKI", 1, DateTime.Now, DateTime.Now,
DateTime.Now, 1, 0.1m, "ship name", "ship address" , "paris", "idf", "75000",
"france");
order.OrderDetailCollection.Add(order.OrderID, 1, 15.6m, 10, 0.02f);
order.OrderDetailCollection.Add(order.OrderID, 2, 122.6m, 43, 0.03f);
DataRepository.OrderProvider.DeepSave(order);
Console.WriteLine("new order saved: orderId is: " + order.OrderID.ToString());
1.3.7. 多資料庫支援
同時支援多個不同的資料庫進行操作,在el 設定檔中配置不同的資料庫連接或者在代
碼中動態產生不同的資料庫連接,達到同時使用不同類型資料庫的目的。
/*
You can configure multiple data provider in the configuration console, and
write code to acces a specific one, instead of the default.
*/
using Northwind.DataAccessLayer;
SqlDataProvider myRepository = DataRepository.Providers["my second data
provider"] as Northwind.DataAccessLayer.SqlClient.SqlDataProvider;
this.listBox1.DataSource = myRepository.ProductProvider.GetAll();
this.listBox1.DisplayMember = "ProductName";
this.listBox1.ValueMember = "ProductID";
//Or if you can't have it pre-configured, you can change the connection
string at runtime.
using Northwind.DataAccessLayer;
//New syntax using a declared connection string:
TList<Products> list =
DataRepository.Connections["NorthwindConnectionString2"].Provider.CustomersProvide
r.GetAll();
//New syntax using a dynamic connection string:
DataRepository.AddConnection("DynamicConnectionString", "Data
Source=(local);Initial Catalog=Northwind;Integrated Security=true;");
TList<Products< list =
DataRepository.Connections["DynamicConnectionString"].Provider.ProductsProvider.Ge
tAll();
this.listBox1.DataSource = list;
this.listBox1.DisplayMember = "ProductName";
this.listBox1.ValueMember = "ProductID";
1.4. 配置nettiers模板
1.4.1. Datasource目錄:
SourceDatabase 資料庫名字和串連參數,在codesmith explore中有配置介面彈出
SourceTables 在資料表裡面需要實體化的表
EntireDatabase 明確在資料庫中需要實體化的表,這個設定將取代SourceTables 的設定
1.4.2. General 目錄
OuputDirectory 輸出目錄,在codesmith explore裡面有配置介面彈出
BusinessLogicLayerFolderName 邏輯層子目錄名,推薦置空
DataAccessLayerFolderName 資料層子目錄名,推薦值:DataAccessLayer
SqlFolderName 預存程序指令碼目錄名,推薦:SQL
NameSpace 項目的命名空間,名稱和目錄同。
GenerateUnitTest 聲明產生nunit測試專案名
VsNetIntegration 聲明是整個的產生一個工程還是按層分開產生工程
VsNetVersion Vs.net的版本
1.4.3. Webservice參數
GenerateWebService 聲明是否產生webservice服務
WebServiceOutputPath Webservice的組建檔案路徑
WebServiceUrl 資料層子目錄名,推薦值:DataAccessLayer
SqlFolderName 指向WebServiceOutputPath 的url
配置完成後可以儲存為設定檔,下次只需要載入即可。
新增了web層的模板,叫weblayer,實現單表的增刪改查;
給一個配置好的例子,對sqlserver2000的資料庫northwind的配置例子,見netier目錄下面
property.xml檔案,可以直接載入然後產生對應的代碼,產生的是完整的工程,可以直接編譯
運行。
1.1. 概述:
使用NetTier模板產生的.net代碼,包括完整的資料層,使用的技術是微軟的
EnterpriseLibrary1.1版本,對應每張表都產生相對應的增刪改查函數和預存程序,在查詢中支
持多欄位查詢和翻頁。資料層為工廠模型,只要調用DataRepository 類即可擷取相應表的接
口執行個體,然後可以對改表進行操作了。對於多表關聯操作,在父表中可以擷取子集的查詢記
錄,儲存在IList 容器裡面,對於子表,提供父表的對象執行個體。對於資料庫的操作提供事務功
能。對於更加複雜的操作,直接提供EnterpriseLibrary的資料庫操作執行個體,直接進行操作。
特徵:
1、 產生vs.net工程和解決方案;
2、 整合EnterpriseLibrary1.1版本,對於資料庫連結可以直接使用EnterpriseLibrary的配置文
件;
3、 資料表和實體的映射關係是1:1的,每張表都有一個實體產生,在實體裡面對應了每個
欄位,實體類是序列化的,有trigger事件,支援枚舉類型的欄位;
4、 對於表和檢視窗產生的實體的操作包括:基本的CRUD操作:UPDATE, DELETE, INSERT,
SELECT ALL, PAGED SELECT, FIND;支援主鍵、外鍵、多表關聯、排序、分頁、sql
語句、視圖查詢;
5、 擷取強型別的資料集儲存在Ilist或者Vlist裡面,可以綁定到DataGrid、GridView或
者其他的頁面控制項中,支援表格排序;
6、 產生webservice 服務進行資料分發;
7、 建立預存程序指令碼,而且自動安裝到資料庫伺服器上面;
8、 產生nant的完整的build.xml 檔案,可以自動編譯、測試代碼,產生chm 格式的api
文檔;
9、 根據資料庫產生完整的資料驗證規則,包括一個管理規則的架構;
10、 每個表都有一個實體類,你可以在你的客戶代碼裡面繼承,然後增加自己的處理方
法;
11、 產生資料來源可以讓你你無需再去處理資料來源的問題了;
12、 建立全套的web admin使用者控制項,你可以對資料庫進行web管理;
13、 完整的nunit測試;
14、 完整的注釋,符合微軟的命名規則;
15、 nettiers 模板是免費開源的。
1.2. 架構結構:
資料邏輯包括客戶商務邏輯組件、資料介面邏輯組件(持久層邏輯),整個設計建築在el
上面。
下面以northwind資料庫的單表employee為例進行講解。
Employee資料表結構:
產生的OO 結構:
介面統一的調用DataRepository 擷取各功能塊的provider,然後進行單表的增刪改查操
作,如果需要更加複雜的商務邏輯,比如要用到事務來同時處理幾個表,那麼需要另外寫業務
邏輯代碼了,這些邏輯層代碼可以放在bl 層裡面。值得一提的是,現在在bl 層裡面產生的代
碼,只有最基本和通用的商務邏輯,只產生了單表資料的實體類VO、單表資料各欄位的處理
和資料集合的排序、檢索等處理。
EmployeesCollection
EmployeesCollectionBase
Employees
EmployeesBase EmployeesVO
在DataRepository 裡面擷取各功能模組的provider的方法是static 方法,得到的是各
個sqlprovider 的執行個體,而提供給外界使用的是其對應的抽象類別定義的方法。
執行個體的調用順序是:
:
DataRepository
:
SqlDataProvider
:
SqlEmployeesProviderBase
1: EmployeesProvider
2: GetAll
3: GetByEmployeeID
分析DataRepository.EmployeesProvider.GetAll()的操作:執行個體化的順序是
DataRespository 類裡面維護了一個全域的變數Current,這個Current實際上是
SqlDataProvider 的執行個體,而Current是DataProviderBase 類型,關係為:
DataProviderBase
SqlDataProvider
(from sqlclient)
在DataRepository 中擷取EmployeesProvider的時候,實際上是調用了
SqlDataProvider 裡面的方法EmployeesProvider(),new 了一個SqlEmployeesProvider 實
例,而這個執行個體中所有的方法的實現在SqlEmployeesProviderBase類中實現的,因為
SqlEmployeesProvider繼承了SqlEmployeesProviderBase類,這個類相當於是dao 層,直接進行
資料庫操作。
SqlEmployeesProviderBase
EmployeesProviderBase
(from base)
SqlEmployeesProvider
在產生各個sqlprovider 執行個體的時候,需要先執行個體化SqlDataProvider,這個用的是
Activator 類根據設定檔提供的這個類的名字產生的,nettier為了做到對不同資料庫的支
持,提供了一個設定檔nettiersconfigdata.config 和讀取這個設定檔的dll:
NetTiers.Configuration.dll。
Activator 類可以動態構造對象,有點像Java裡面的
Class.forName(ClassName).newInstance()語句,因為用Activator 類構造對象,其類名在
編譯時間可以不確定,所以可以用來做外掛程式的介面,做出Winamp 那種可以外加DLL 外掛程式的程式
來。
1.3. 調用介面的方法:
1.3.1. 擷取所有資料
擷取所有的Employee資料,按照LastName欄位進行排序:
using Northwind.DataAccessLayer;
// Get all the employee, sort it on the LastName and print them out
TList<Employees> employees = DataRepository.EmployeeProvider.GetAll();
employees.Sort(EmployeeColumns.LastName, ListSortDirection.Ascending);
foreach(Employee employee in employees)
{
Console.WriteLine("{1} {0}", employee.FirstName, employee.LastName);
}
1.3.2. 新增資料
建立一個新的employee 並且儲存
using Northwind.DataAccessLayer;
// Create a new record and save
Employee employee = new Employee();
employee.FirstName = "John";employee.LastName = "Doe";
employee.BirthDate = DateTime.Now;employee.Address = "10 , fake street";
employee.City = "Metroplolis";employee.Country = "USA";
employee.HireDate = DateTime.Now;
employee.HomePhone = "0123456789";
employee.Notes = "This is a fake employee";
employee.Title = "M";
employee.TitleOfCourtesy = "Dear";
employee.PostalCode = "5556";
employee.Region = "New-York";
DataRepository.EmployeeProvider.Insert(employee);
//look, new id already populated
Console.WriteLine("New Employee ID" + employee.EmployeeId);
1.3.3. 修改資料
按照下標擷取資料並且修改資料;
using Northwind.DataAccessLayer;
// Select by Index and Update
TList<Employees> employees =
DataRepository.EmployeeProvider.GetByLastName("Doe");
if (employees.Count == 1)
{
employees[0].Notes = "This is a modified fake employee";
DataRepository.EmployeeProvider.Save(employees[0]);
Console.Write(employees[0]);
}
1.3.4. 刪除資料
通過主鍵查詢資料並且刪除
using Northwind.DataAccessLayer;
// Select by primary key and Delete
// (Demonstrate that insert, update, delete methods can also take collection
as parameter)
Employee employee = SqlDataRepository.EmployeeProvider.GetByEmployeeID(13);
DataRepository.EmployeeProvider.Delete(employees);
1.3.5. 事務控制
事務控制執行個體,可以用事務控制插入、修改、刪除的操作,保證全部成功或者失敗復原;
using Northwind.DataAccessLayer;
// The SqlClient can work with transactions.
// Also show the Save method, wich encapsulate the use of Insert, Update and
Delete methods.
TransactionManager transaction = DataRepository.CreateTransaction();
transaction.BeginTransaction(/*IsolationLevel.ReadUncommited*/);
try
{
// Insert
Employee employee = new Employee();
employee.FirstName = "John";
employee.LastName = "Doe";
employee.BirthDate = DateTime.Now;
employee.Address = "10 , fake street";
employee.City = "Metroplolis";
employee.Country = "USA";
employee.HireDate = DateTime.Now;
employee.HomePhone = "0123456789";
mployee.Notes = "This is a fake employee";
employee.Title = "M";
employee.TitleOfCourtesy = "Doctor";
employee.PostalCode = "5556";
employee.Region = "New-York";
DataRepository.EmployeeProvider.Save(transaction, employee);
// modify the employee instance
employee.Notes = "This is a modified fake employee";
// Update
DataRepository.EmployeeProvider.Save(transaction, employee);
transaction.Commit();
Console.WriteLine("ok");
}
catch(Exception ex)
{
try { transaction.Rollback();} catch(){}
Console.WriteLine("nok : {0}", ex);
}
1.3.6. 關聯儲存
深度儲存,可以同時儲存父物件和子集
/*
DeepSave helper method can help you to save an object and its children in
one call.
*/
using Northwind.DataAccessLayer;
Order order = Order.CreateOrder("ALFKI", 1, DateTime.Now, DateTime.Now,
DateTime.Now, 1, 0.1m, "ship name", "ship address" , "paris", "idf", "75000",
"france");
order.OrderDetailCollection.Add(order.OrderID, 1, 15.6m, 10, 0.02f);
order.OrderDetailCollection.Add(order.OrderID, 2, 122.6m, 43, 0.03f);
DataRepository.OrderProvider.DeepSave(order);
Console.WriteLine("new order saved: orderId is: " + order.OrderID.ToString());
1.3.7. 多資料庫支援
同時支援多個不同的資料庫進行操作,在el 設定檔中配置不同的資料庫連接或者在代
碼中動態產生不同的資料庫連接,達到同時使用不同類型資料庫的目的。
/*
You can configure multiple data provider in the configuration console, and
write code to acces a specific one, instead of the default.
*/
using Northwind.DataAccessLayer;
SqlDataProvider myRepository = DataRepository.Providers["my second data
provider"] as Northwind.DataAccessLayer.SqlClient.SqlDataProvider;
this.listBox1.DataSource = myRepository.ProductProvider.GetAll();
this.listBox1.DisplayMember = "ProductName";
this.listBox1.ValueMember = "ProductID";
//Or if you can't have it pre-configured, you can change the connection
string at runtime.
using Northwind.DataAccessLayer;
//New syntax using a declared connection string:
TList<Products> list =
DataRepository.Connections["NorthwindConnectionString2"].Provider.CustomersProvide
r.GetAll();
//New syntax using a dynamic connection string:
DataRepository.AddConnection("DynamicConnectionString", "Data
Source=(local);Initial Catalog=Northwind;Integrated Security=true;");
TList<Products< list =
DataRepository.Connections["DynamicConnectionString"].Provider.ProductsProvider.Ge
tAll();
this.listBox1.DataSource = list;
this.listBox1.DisplayMember = "ProductName";
this.listBox1.ValueMember = "ProductID";
1.4. 配置nettiers模板
1.4.1. Datasource目錄:
SourceDatabase 資料庫名字和串連參數,在codesmith explore中有配置介面彈出
SourceTables 在資料表裡面需要實體化的表
EntireDatabase 明確在資料庫中需要實體化的表,這個設定將取代SourceTables 的設定
1.4.2. General 目錄
OuputDirectory 輸出目錄,在codesmith explore裡面有配置介面彈出
BusinessLogicLayerFolderName 邏輯層子目錄名,推薦置空
DataAccessLayerFolderName 資料層子目錄名,推薦值:DataAccessLayer
SqlFolderName 預存程序指令碼目錄名,推薦:SQL
NameSpace 項目的命名空間,名稱和目錄同。
GenerateUnitTest 聲明產生nunit測試專案名
VsNetIntegration 聲明是整個的產生一個工程還是按層分開產生工程
VsNetVersion Vs.net的版本
1.4.3. Webservice參數
GenerateWebService 聲明是否產生webservice服務
WebServiceOutputPath Webservice的組建檔案路徑
WebServiceUrl 資料層子目錄名,推薦值:DataAccessLayer
SqlFolderName 指向WebServiceOutputPath 的url
配置完成後可以儲存為設定檔,下次只需要載入即可。
新增了web層的模板,叫weblayer,實現單表的增刪改查;
給一個配置好的例子,對sqlserver2000的資料庫northwind的配置例子,見netier目錄下面
property.xml檔案,可以直接載入然後產生對應的代碼,產生的是完整的工程,可以直接編譯
運行。