【问题标题】:How to provide a default implementation for LINQ to SQL's OnValidate method?如何为 LINQ to SQL 的 OnValidate 方法提供默认实现?
【发布时间】:2010-02-02 10:41:34
【问题描述】:

我正在尝试在LINQ to SQL 实体的基类中实现验证框架。我遇到的问题是让 OnValidate 事件正确触发。

原因是 OnValidate 被标记为部分,所以我不能在基类中提供默认实现;它被 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);
    }
}

【问题讨论】:

    标签: c# linq-to-sql validation inheritance


    【解决方案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 类中的 Validate 方法(当然,您必须创建它)。

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

    【讨论】:

      【解决方案2】:

      如果您正在寻找要继承的 BaseDataContext,我的示例如下:

      public class BaseDataContext : DataContext
      {
        // constructor is needed if you have different contexts
          public BaseDataContext(string fileOrServerOrConnection) : base(fileOrServerOrConnection)
          {
          }
      
          public override void SubmitChanges(ConflictMode failureMode)
          {
              try
              {
                  base.SubmitChanges(failureMode);
              }
              catch (Exception ex)
              {
      // do whatever you would like with the exception
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-07
        • 1970-01-01
        • 2023-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-18
        • 1970-01-01
        相关资源
        最近更新 更多