ASPNET AdventureWorks貿易系統分析
AdventureWorks貿易系統是一個使用N層架構和ASPNET 技術創建的Web站點該站點實現了貿易系統的部分功能在實現過程中重點使用了一些集成可重用組件這應該是大家閱讀的重點所在本系列文章包括篇第一篇簡單介紹一下系統概況和數據庫設計第二篇講解數據訪問層的實現第三篇說明構建Web站點的方法通過這些內容讀者將學習和實踐多方面的知識例如N層架構應用使用數據訪問應用程序塊創建數據訪問層使用泛型集合實現數據綁定使用企業庫的異常處理塊統一處理異常母版頁應用等等
業務過程
AdventureWorks貿易系統實現了貿易系統的部分功能例如產品類別的顯示等等有關該系統的功能讀者可通過下面所描述的業務過程來了解AdventureWorks系統的業務過程包括
產品類別顯示過程該過程允許用戶顯示AdventureWorks數據庫中包括的所有類別用戶可單擊所顯示類別列表中的特定類別以便顯示所有相關的子類別
產品子類別顯示過程在獲得類別列表後接著可以顯示所選中類別的所有子類別
產品顯示過程通過這個過程可顯示每個子類別中的產品列表單擊特定子類別可獲取該產品子類別包括的產品列表
正如讀者看到的這些過程非常簡單因為本實例主要關注的是集成可重用組件例如數據訪問塊異常管理塊將數據庫表轉換為對象的泛型轉換創建和利用存儲過程等下面介紹一下系統架構方面的內容
系統架構
圖說明了貿易系統的架構
數據庫設計
既然大家已經了解了包括的業務過程那麼下面將講解實現解決方案所需的各個構造塊為達到本實例目的實例余下部分的討論將分為()數據庫設計()實現CLR存儲過程()實現數據訪問和業務邏輯組件()實現Web站點下面首先介紹數據庫方面的設計
本實例使用的AdventureWorks數據庫包括多個表但是該實例僅使用了其中的三個表ProductCategoryProductSubcategory和Product以下說明表的結構首先是ProductCategory表
ProductSubcategory表定義如下
下表說明了Product表的結構
下一步是說明創建操作這些結構的存儲過程
實現CLR存儲過程
SQL Server 最優雅的功能之一是集成NET CLR集成CLR的SQL Server在多個重要的方面擴展了SQL Server功能利用這種集成可創建數據庫對象(例如存儲過程)用戶定義函數以及使用現代面向對象語言(例如VBNET和C#)創建觸發器為達成本實例目的將說明使用C#創建存儲過程的方法
首先在Visual Studio 中以Visual Studio 作為編程語言創建一個新的名為AdventureWorksDatabaseObjects的SQL Server項目由於創建的是數據庫項目所以需要關聯數據源與項目在創建項目的同時Visual Studio將要求開發人員要麼選擇現有數據庫引用要麼添加新數據庫引用選擇AdventureWorks作為數據庫一旦創建項目則在項目菜單中選擇添加存儲過程選項在添加新項對話框中輸入StoredProcedurescs接著單擊添加按鈕在創建類之後可根據以下內容修改類中代碼
示例實現CLR存儲過程
using System;
using SystemData;
using SystemDataSqlClient;
using SystemDataSqlTypes;
using MicrosoftSqlServerServer;
public partial class StoredProcedures
{
[MicrosoftSqlServerServerSqlProcedure]
public static void GetProductCategories()
{
using (SqlConnection connection = new SqlConnection(context connection=true))
{
connectionOpen();
string sqlCommand = Select ProductCategoryID Name rowguid +
ModifiedDate from ProductionProductCategory;
SqlCommand command = new SqlCommand(sqlCommand connection);
SqlDataReader reader = commandExecuteReader();
SqlContextPipeSend(reader);
}
}
[MicrosoftSqlServerServerSqlProcedure]
public static void GetProductSubcategories(int productCategoryID)
{
using (SqlConnection connection = new SqlConnection(context connection=true))
{
connectionOpen();
string sqlCommand = Select ProductSubcategoryID ProductCategoryID Name + rowguid ModifiedDate from ProductionProductSubcategory + Where ProductCategoryID = + productCategoryID;
SqlCommand command = new SqlCommand(sqlCommand connection);
SqlDataReader reader = commandExecuteReader();
SqlContextPipeSend(reader);
}
}
[MicrosoftSqlServerServerSqlProcedure]
public static void GetProducts(int productSubcategoryID)
{
using (SqlConnection connection = new SqlConnection(context connection=true))
{
connectionOpen();
string sqlCommand = Select ProductID Name ProductNumberMakeFlag + FinishedGoodsFlag Color SafetyStockLevel ReorderPointStandardCost + ListPrice Size SizeUnitMeasureCode WeightUnitMeasureCode + WeightDaysToManufacture ProductLineClass Style + ProductSubcategoryID ProductModelIDSellStartDateSellEndDate + DiscontinuedDate rowguid ModifiedDate from ProductionProduct + Where ProductSubcategoryID = + productSubcategoryIDToString();
SqlCommand command = new SqlCommand(sqlCommand connection);
SqlDataReader reader = commandExecuteReader();
SqlContextPipeSend(reader);
}
}
};
在示例中首先導入所需命名空間接著聲明StoreProcedures類導入的重要命名空間之一是MicrosoftSqlServerServer該命名空間包括兩個針對內部過程提供程序的重要類
SqlContext該類封裝了為在SQL Server 中執行內部過程所需的擴展對象另外該類還提供了事務和數據庫連接它們是常規執行環境中的一部分
SqlPipe該類通常可將表格式結果和消息發送給客戶端就概念而言該類與ASPNET中的Response類相似因此可用於將消息發送給調用者
StoredProcedures類包括三個靜態方法GetProductCategories()GetProductSubcategories()和GetProducts()正如名稱暗示GetProductCategories()方法僅從AdventureWorks數據庫中返回所有類別信息GetProductSubcategories()方法可返回輸入特定類別的子類別信息GetProducts()方法可返回輸入特定產品子類別的所有產品信息以下內容將詳細講解GetProductCategories()方法
在GetProductCategories()方法內部首先使用SqlConnection對象數據庫連接注意傳遞給SqlConnection對象構造函數的連接字符串設置為context connection=true這意味著使用登錄用戶的上下文打開數據庫連接
using (SqlConnection connection = new SqlConnection(context connection=true))
此時使用Open()方法打開數據庫連接
connectionOpen();
然後設置將要執行的SQL命令在這種情況下從ProductCategory表中獲取所有記錄
string sqlCommand = Select ProductCategoryID Name rowguid ModifiedDate from + ProductionProductCategory;
接著將SQL查詢語句和SqlConnection對象作為參數傳遞給SqlCommand類的構造函數以便創建SqlCommand對象實例
SqlCommand command = new SqlCommand(sqlCommand connection);
此後
通過調用SqlCommand對象的ExecuteReader()方法執行SQL查詢
SqlDataReader reader = commandExecuteReader();
使用SqlPipe對象將表格式結果和消息返回給客戶端這是通過SqlPipe類的Send()方法來實現
SqlContextPipeSend(reader);
Send()方法提供了多種重載以便通過管道將數據發送給調用方應用程序
StoredProcedures類中所有方法都使用Send()方法來將表格式結果以SqlDataReader對象格式發送給客戶應用程序由於GetProductSubcategories()和GetProducts()與GetProductCategories()方法的實現非常相似因此不會對前二者進行詳細講解
既然創建了存儲過程那麼就可以非常簡單和直接的應用它們了在應用之前需要首先生成項目為了生成項目可在Visual Studio 的菜單中選擇生成→生成AdventureWorksDatabaseObjects如果出現編譯錯誤則將顯示在錯誤列表面板中一旦生成項目那麼就能夠通過選擇菜單中的生成→部署AdventureWorksDatabaseObjects項來將其部署到SQL Server中這樣不僅在SQL Server中注冊了程序集而且還在SQL Server中部署了存儲過程當存儲過程部署到SQL Server後接著可以在數據訪問層調用它這些內容將在下一節講解
在執行存儲過程之前記住使用SQL Server Management Studio執行以下代碼以便在SQL Server中執行受管代碼
EXEC sp_configure clr enabled ;
RECONFIGURE WITH OVERRIDE;
GO
雖然該實例使用Visual Studio創建受管存儲過程但是開發人員還是能夠輕松使用文本編輯器(例如記事本)獲得相同的結果
另外可能有些讀者會感到疑惑到底何時使用TSQL何時使用受管代碼呢?這個問題的答案很簡單受管代碼比TSQL更加適合實現復雜的執行邏輯同時它對於完成許多復雜任務都具有廣泛支持包括字符串處理和正則表達式TSQL比較適合實現具有少量或者非過程性邏輯的數據訪問的情況本實例中的存儲過程很簡單最好使用TSQL編寫然而卻使用了受管代碼的方法這主要是為了說明創建和使用受管存儲過程的方法
小結
本文對貿易系統的業務過程系統架構數據庫設計和CLR存儲過程的實現進行了介紹貿易系統與其他很多實例不同的是這個實例充分利用了集成重用塊EntLib尤其是在實現數據訪問異常處理等方面這可能是讀者應該重點學習和關注的方面在下一篇文章中將介紹實現數據訪問層的方法
From:http://tw.wingwit.com/Article/program/net/201311/12279.html