2010-02-02 60 views
0

我正试图在LINQ to SQL实体的基类中实现验证框架。我遇到的问题是让OnValidate事件正确触发。如何为LINQ to SQL的OnValidate方法提供默认实现?

原因是OnValidate被标记为partial,所以我无法在基类中提供默认实现;它被LINQ to SQL类声明的新方法隐藏。

我该如何解决这个问题,以便基类中的OnValidate事件会被自动调用?

示例代码如下所示。

public class EntityBase 
{ 
    public bool IsValid 
    { 
     get { return (GetValidationErrors().Count() == 0); } 
    } 

    public virtual IEnumerable<ValidationError> GetValidationErrors() 
    { 
     yield break; 
    } 

    public void OnValidate(System.Data.Linq.ChangeAction action) 
    { 
     //This never gets fired unless I call explicitly in the derived class. 
     if (!IsValid) 
     { 
      StringBuilder sb= new StringBuilder(); 
      sb.AppendLine("Validation errors prevent saving"); 
      foreach (ValidationError error in GetValidationErrors()) 
      { 
       sb.AppendLine(String.Format("{0}: {1}", error.PropertyName, error.ErrorMessage)); 
      } 
      throw new ApplicationException(sb.ToString()); 
     } 
    } 
} 

public partial class LinqThingy: EntityBase 
{ 
    public override IEnumerable<ValidationError> GetValidationErrors() 
    { 
     if (String.IsNullOrEmpty(Name)) yield return new ValidationError("Name required", "Name"); 
    } 

    //Eww nasty, don't want to have to do this. 
    partial void OnValidate(System.Data.Linq.ChangeAction action) 
    { 
     base.OnValidate(action); 
    } 
} 

回答

1

您可以覆盖DataContext类中的SubmitChanges(ConflictMode)方法。这将确保所有实体在持续之前得到验证。这样你就不必为实体创建一个自定义的基类。下面是如何扩展DataContext类的例子:

public partial class NorthwindDataContext 
{ 
    public override void SubmitChanges(ConflictMode failureMode) 
    { 
     EntityValidator.Validate(this.GetChangedEntities()); 
     base.SubmitChanges(failureMode); 
    } 

    private IEnumerable<object> GetChangedEntities() 
    { 
     ChangeSet changes = this.GetChangeSet(); 
     return changes.Inserts.Concat(changes.Updates); 
    } 
} 

在自定义验证逻辑上面的例子进入在EntityValidator类的验证方法(你必须创建它当然)。

This article显示了如何使用O/RM技术(如LINQ to SQL)验证实体。虽然它使用企业库验证应用程序块,但该文章可能适用于您的情况。