The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

善用 LINQ to SQL 中的 partial class 機制進行資料格式驗證

我們通常會使用 DetailsView 或 FormView 控制項進行資料的新增、編輯、刪除等動作,而通常我們會在裡面放置許多 Validator 控制項以驗證資料格式是否正確,不過當進行較大的專案時,開發人數通常會比較多,而且人員之間的分工也會比較明確,有的人做 SA、有的人做 DBA、有的人做 ASP.NET UI Process 開發...等等,在分層負責的情況下若能夠有效分割工作,不但專案品質會比較高,大家在寫程式的過程中也會比較專注。

就拿驗證輸入資料的部分來討論,SA/SD 在傳遞專案規格給開發人員時,總是難免有東西沒講清楚,而導致某些資料輸入的驗證沒有做好;或者是專案需求不斷變更,而導致可能有些輸入驗證的規則遺漏了更新程式碼,若能從「資料的角度」出來來驗證輸入的資料,而非「操作介面的角度」來驗證資料,應該是比較直覺且有效的方式,而 LINQ to SQL 正好就實做出了這一點。

當我們用 LINQ to SQL Designer 設計完資料物件模型,預設就有定義一些你可以自行實做的 partial method,例如���之前文章提到過的 OnCreated() 方法,可用於資料物件(Entity)產生時給予資料物件的預設值。今天要講的是另一個 OnValidate() 方法,可用於當 LINQ to SQL 在執行 Insert, Update 或 Delete 等動作之前,對資料物件進行資料驗證的動作。

底下是一個簡單的驗證範例:

public partial class 產品資料
{
    partial void OnValidate(System.Data.Linq.ChangeAction action)
    {
        if (action == System.Data.Linq.ChangeAction.Insert 
            || action == System.Data.Linq.ChangeAction.Update)
        {
            if (!this._繳費方式.HasValue)
            {
                throw new Exception("您沒有輸入「繳費方式」無法儲存產品資料");
            }

            if (this.產品類別.名稱 == "電子商務類")
            {
                if (this.產品售價 < 2000)
                {
                    throw new Exception("電子商務類產品不得設定低於 2000 元。");
                }
            }
        }
    }
}

上面這段程式的「白話文」就是,當使用者要新增資料時或更新資料時,會先檢查「繳費方式」有沒有輸入資料,若沒輸入資料則丟出一個例外事件(Exception)。若「產品資料」的「產品類別」定義為「電子商務類」,當產品售價低於 2000 時則丟出一個例外事件(Exception)。

你可以看到我對產品類別的判斷條件跟「資料格式(Data Format)」是無關的,而是跟「商業邏輯(Business Logic)」有關係,在實務上資料格式異動的機會不太大(總是有例外的),但是商業邏輯就很有可能經常改變,將商業邏輯的判斷寫在這裡會比寫在每一支 ASP.NET 頁面程式裡來的清楚明瞭而直覺,不過這並不代表在 ASP.NET 頁面中就不需額外做出判斷,要做好一個完美的使用者介面,需要考量的細節是很多的,況且客戶的需求總是讓你料想不到,只是你可以把 OnValidate() 方法視為從 ASP.NET 輸入資料到 SQL Server 中的最後一道防線。

當然,你也可以把「最後一道防線」設定在資料庫系統中,例如說撰寫觸發程序(Trigger)或預儲程序(Stored Procedure),但這沒有一定的規則,全看你怎麼規劃整個系統開發的架構,而我個人是偏好寫 C# 大於 T-SQL 啦。^_^