2009-08-10 35 views
1

我剛開始使用LINQ to SQL類,並且非常喜歡這樣如何幫助我編寫可讀代碼。 在文檔中,典型的例子指出,做自定義驗證,爲您創造一個局部類作爲這樣::LINQ to SQL驗證所有字段,而不僅僅是第一次停止失敗的字段

partial class Customer 
{ 
    partial void OnCustomerIDChanging(string value) 
    { 
     if (value=="BADVALUE") throw new NotImplementedException("CustomerID Invalid"); 
    } 
} 

同樣地,對於其他領域... 然後在代碼隱藏,我把這樣的事情以顯示錯誤消息,並保持用戶在同一頁面上,以糾正錯誤。

public void CustomerListView_OnItemInserted(object sender, ListViewInsertedEventArgs e) 
{ 
    string errorString = ""; 
    if (e.Exception != null) 
    { 
     e.KeepInInsertMode = true; 
     errorString += e.Exception.Message; 
     e.ExceptionHandled = true; 
    } 
    else errorString += "Successfully inserted Customer Data" + "\n"; 
    errorMessage.Text = errorString; 
} 

好吧,這很容易,但隨後停止只要第一拋出異常驗證領域的休息!意思是如果用戶做出的模式不止一個錯誤,她/他/它只會被通知第一個錯誤。 是否有另一種方法來檢查所有輸入並顯示每個錯誤? 任何建議表示感謝,謝謝。

回答

0

我想通了。在第一次失敗的驗證中,我沒有拋出異常,而是將一個錯誤消息存儲在一個帶有靜態變量的類中。要做到這一點,我謹向這樣DataContext類::

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 

/// <summary> 
/// Summary description for SalesClassesDataContext 
/// </summary> 
public partial class SalesClassesDataContext 
{ 
    public class ErrorBox 
    { 
     private static List<string> Messages = new List<string>(); 
     public void addMessage(string message) 
     { 
      Messages.Add(message); 
     } 
     public List<string> getMessages() 
     { 
      return Messages; 
     } 
    } 
} 
對應於每個表類

,我將繼承新定義的類這樣的:

public partial class Customer : SalesClassesDataContext.ErrorBox 

只有在功能OnValidate我會拋出一個異常的情況下,錯誤的數量不是0.因此,不試圖插入,並保持用戶在同一輸入頁面,而不會丟失他們輸入的數據。

+1

Slabo,這不是一個論壇網站,因此,除非它實際上是一個答案,否則你不應該對自己的問題發表一個答案。 如果您有更多需要添加的內容,請修改您的原始問題。 – 2009-08-10 17:20:45

0

不適用於LINQ。假設你將在之前驗證輸入,並將其提供給LINQ。

你所看到的是有例外的自然行爲。

+0

感謝您的建議。我認爲你的意思是使用ASP.NET的驗證控件進行驗證?我更喜歡不這樣做,我更喜歡將asp.net部分限制爲簡單的文本框,列表視圖或gridview控件等。 但可能不是拋出異常,我可以觸發一些甚至存儲錯誤。 – Slabo 2009-08-10 12:21:18

1

這看起來像Enterprise Library Validation Application Block(VAB)的工作。 VAB被設計爲返回所有錯誤。除此之外,它不會拋出異常,所以您可以簡單地要求它爲您驗證類型。

當您決定使用VAB時,我建議您不要使用LINQ to SQL的OnXXXChanging和OnValidate方法。最好重寫DataContext類的SubmitChange(ConflictMode)方法以調用VAB的驗證API。這可以讓您的業務實體保持您的驗證邏輯,從而保持您的實體清潔。

請看下面的例子:

public partial class NorthwindDataContext 
{ 
    public ValidationResult[] Validate() 
    { 
     return invalidResults = (
      from entity in this.GetChangedEntities() 
      let type = entity.GetType() 
      let validator = ValidationFactory.CreateValidator(type) 
      let results = validator.Validate(entity) 
      where !results.IsValid 
      from result in results 
      select result).ToArray();    
    } 

    public override void SubmitChanges(ConflictMode failureMode) 
    { 
     ValidationResult[] this.Validate(); 

     if (invalidResults.Length > 0) 
     { 
      // You should define this exception type 
      throw new ValidationException(invalidResults); 
     } 

     base.SubmitChanges(failureMode); 
    } 

    private IEnumerable<object> GetChangedEntities() 
    { 
     ChangeSet changes = this.GetChangeSet(); 

     return changes.Inserts.Concat(changes.Updates); 
    } 
} 

[Serializable] 
public class ValidationException : Exception 
{ 
    public ValidationException(IEnumerable<ValidationResult> results) 
     : base("There are validation errors.") 
    { 
     this.Results = new ReadOnlyCollection<ValidationResult>(
      results.ToArray()); 
    } 

    public ReadOnlyCollection<ValidationResult> Results 
    { 
     get; private set; 
    } 
} 

調用validate()方法將返回所有錯誤的集合,但而不是調用驗證(),我會簡單地調用的SubmitChanges()時,你」準備堅持下去。 SubmitChanges()現在將檢查錯誤並在其中一個實體無效時拋出異常。由於錯誤列表發送到ValidationException,你可以遍歷上漲調用堆棧中的錯誤,並把它們呈現給用戶,如下所示:

try 
{ 
    db.SubmitChanges(); 
} 
catch (ValidationException vex) 
{ 
    ShowErrors(vex.ValidationErrors); 
} 

private static void ShowErrors(IEnumerable<ValidationResult> errors) 
{ 
    foreach(var error in errors) 
    { 
     Console.WriteLine("{0}: {1}", error.Key, error.message); 
    } 
} 

當你使用這種方法,你確保你的實體在將它們保存到數據庫之前總是經過驗證

Here是一篇很好的文章,它解釋瞭如何將VAB與LINQ to SQL集成。如果你想在LINQ to SQL中使用VAB,你一定要閱讀它。

相關問題