如何为LINQ to SQL的OnValidate方法提供默认实现?

时间:2010-02-02 10:41:35

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

我正在尝试在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);
    }
}

2 个答案:

答案 0 :(得分:2)

您可以覆盖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。虽然它使用企业库验证应用程序块,但该文章可能适用于您的情况。

答案 1 :(得分:0)

如果您正在寻找要继承的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
        }
    }
}