代码之家  ›  专栏  ›  技术社区  ›  emptyset

LINQ to SQL:OnValidate()和自定义域模型类

  •  2
  • emptyset  · 技术社区  · 15 年前

    NerdDinner Tutorial ,我试图找到一种对不依赖于LINQ到SQL生成的分部类的属性执行验证的好方法。以下是我迄今为止所做工作的一些示例代码:

    public abstract class DomainEntity
    {
        public IEnumerable<ValidationError> ValidationErrors { get; private set; }
    
        public bool Validate()
        {
            bool isValid = false;
    
            if (this.ValidationErrors != null)
                this.ValidationErrors = null;
    
            this.ValidationErrors = this.GetValidationErrors();
    
            if (this.ValidationErrors.Count() == 0)
                isValid = true;
    
            return isValid;
        }
    
        protected abstract IEnumerable<ValidationError> GetValidationErrors();
    }
    
    public partial class Email : DomainEntity
    {
        protected override IEnumerable<ValidationError> GetValidationErrors()
        {
            if (!this.ValidateAddress())
                yield return new ValidationError("Address", DomainResources.EmailAddressValidationErrorMessage);
    
            yield break;
        }
    
        partial void OnValidate(ChangeAction action)
        {
            bool isValid = this.Validate();
    
            if (!isValid)
                throw new InvalidEmailException(this);
        }
    
        private bool ValidateAddress()
        {
            // TODO: Use a regex to validate the email address.
    
            return !string.IsNullOrEmpty(this.Address);
        }
    }
    

    其中电子邮件是基于电子邮件表生成的LINQ to SQL类型。由于Email表只是与域模型类(比如“User”)相关的几个实体之一,因此理想情况是创建一个“User”域模型类并使用 Validation Application Block

    public class User
    {
        private Email emailEntity;
    
        [EmailAddressValidator]
        public string EmailAddress
        {
            get { return emailEntity.Address; }
            set { emailEntity.Address = value; }
        }
    }
    

    因此,如果我更改了数据库模式,并且更改是通过LINQ到SQL生成的类进行的,那么我就没有这些孤立的分部类(比如分部类Email)。我还想从集成验证应用程序块属性中获益,这样我就不必像NerdDinner教程中那样维护正则表达式集合。此外,作为域类的用户将是域中的功能单元,而不是电子邮件和其他实体,用于创建视图模型、渲染视图等。但是,如果不执行以下操作,则无法捕获验证调用:

    public abstract class DomainEntity
    {
        public event EventHandler Validation(object sender, EventArgs args);
        protected void OnValidation()
        {
            if (this.Validate != null)
                this.Validate(this, EventArgs.Empty);
        }
    }
    
    public partial class Email
    {
        partial void OnValidate(ChangeAction action)
        {
            this.OnValidation();
        }
    }
    

    1 回复  |  直到 15 年前
        1
  •  1
  •   Neal    15 年前

    将验证视为服务而不是实体的责任,这将使您能够将验证的实现与有效内容的定义分开,并将验证转化为显式操作而不是隐式操作(由L2S管理)。

    http://www.codeplex.com/FluentValidation )为了更好地实施这种方法。