验证此 EF4 验证方法吗?

发布于 2024-10-06 20:00:45 字数 2253 浏览 4 评论 0原文

我对 EF4 非常陌生。我已经发布了几次关于继承、验证的思考,但我的总体目标是尽可能减少我编写的代码量。我(还)对 POCO、大量的 ObjectContext 摆弄不感兴趣:我想要 EF 的好处和最少的编码。

因此,棘手的验证问题。看看这个简化的示例(除了 DRY Buddies 和狡猾的使用别名之外),这看起来是不是一个不太体面的方法?

namespace Model
{
    using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
    using DataAnnotations = System.ComponentModel.DataAnnotations;
    using Validation = Microsoft.Practices.EnterpriseLibrary.Validation;

    [HasSelfValidation]
    [DataAnnotations.MetadataType(typeof(PersonValidator))]
    public partial class Person
    {
        [SelfValidation]
        public Validation.ValidationResults Validate()
        {
            var validationResults = Validation.Validation.Validate(this);

            if (string.IsNullOrEmpty(this.LastName) || this.LastName.Length > 4)
            {
                validationResults.AddResult(new Validation.ValidationResult("This is a test error message for a custom validation error.", this, null, null, null));
            }

            return validationResults;
        }
    }

    [HasSelfValidation]
    public class PersonValidator
    {
        [NotNullValidator(MessageTemplate = "First Name must be supplied.")]
        [ContainsCharactersValidator("Rcd", ContainsCharacters.All, MessageTemplate = "{1} must contains characters \"{3}\" ({4}).")]
        [StringLengthValidator(5, 50, MessageTemplate = "{1} (\"{0}\") must be between {3} ({4}) and {5} ({6}) characters in length.")]
        public string FirstName { get; set; }

        [NotNullValidator(MessageTemplate = "Last Name must be supplied.")]
        [ContainsCharactersValidator("Wes", ContainsCharacters.All, MessageTemplate = "{1} must contains characters \"{3}\" ({4}).")]
        [StringLengthValidator(5, 50, MessageTemplate = "{1} (\"{0}\") must be between {3} ({4}) and {5} ({6}) characters in length.")]
        public string LastName { get; set; }
    }
}

这有一些很酷的事情。我可以这样调用上面的内容:

var validationResults = person.Validate();

但是,如果我只想进行一些基本检查,我可以去掉 Validate()、[SelfValidation] 内容,保留属性,然后只需调用:

var validationResults = Validation.Validate(person);

我只需要包含尽可能多的验证需要,并且 web.config 中的配置为零。

我的前臂剪得怎么样? :)

理查德

I'm very new to EF4. I've posted a couple of times I think regarding inheritance, validation but my overall aim is to reduce the amount of code I write as much as possible. I'm not interested (yet) in POCOs, masses of ObjectContext fiddling: I want the benefit of EF and minimum of coding.

So, the thorny issue of validation. Take a look at this simplified example and (aside from DRY Buddies and dodgy usings aliases), is this looking like a half-decent approach?

namespace Model
{
    using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
    using DataAnnotations = System.ComponentModel.DataAnnotations;
    using Validation = Microsoft.Practices.EnterpriseLibrary.Validation;

    [HasSelfValidation]
    [DataAnnotations.MetadataType(typeof(PersonValidator))]
    public partial class Person
    {
        [SelfValidation]
        public Validation.ValidationResults Validate()
        {
            var validationResults = Validation.Validation.Validate(this);

            if (string.IsNullOrEmpty(this.LastName) || this.LastName.Length > 4)
            {
                validationResults.AddResult(new Validation.ValidationResult("This is a test error message for a custom validation error.", this, null, null, null));
            }

            return validationResults;
        }
    }

    [HasSelfValidation]
    public class PersonValidator
    {
        [NotNullValidator(MessageTemplate = "First Name must be supplied.")]
        [ContainsCharactersValidator("Rcd", ContainsCharacters.All, MessageTemplate = "{1} must contains characters \"{3}\" ({4}).")]
        [StringLengthValidator(5, 50, MessageTemplate = "{1} (\"{0}\") must be between {3} ({4}) and {5} ({6}) characters in length.")]
        public string FirstName { get; set; }

        [NotNullValidator(MessageTemplate = "Last Name must be supplied.")]
        [ContainsCharactersValidator("Wes", ContainsCharacters.All, MessageTemplate = "{1} must contains characters \"{3}\" ({4}).")]
        [StringLengthValidator(5, 50, MessageTemplate = "{1} (\"{0}\") must be between {3} ({4}) and {5} ({6}) characters in length.")]
        public string LastName { get; set; }
    }
}

There's something rather cool about this. I can call the above like this:

var validationResults = person.Validate();

BUT, if I just want some basic checking, I can strip out Validate(), the [SelfValidation] stuff, keep the attributes and then just call:

var validationResults = Validation.Validate(person);

I only need to include as much validation as I need and there's ZERO configuration in web.config.

How's the cut of my jib? :)

Richard

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心是晴朗的。 2024-10-13 20:00:45

我个人不喜欢直接在代码中调用验证,尤其是不直接在实体本身上调用验证。有很多地方你会调用Validate,但很容易忘记调用Validate。相反,让 ObjectContext 自动为所有已更改的实体调用底层验证框架,并在发生验证错误时抛出特殊异常(可以在表示层中捕获)。

您可以通过挂钩 ObjectContext.SavingChanges 事件并在那里触发验证来完成此操作。您可以按如下方式编写部分 ObjectContext

public partial class ModelContainer
{
    partial void OnContextCreated()
    {
        this.SavingChanges +=
            (sender, e) => Validate(this.GetChangedEntities());
    }

    private IEnumerable<object> GetChangedEntities()
    {
        const EntityState AddedAndModified =
            EntityState.Added | EntityState.Modified;

        var entries = this.ObjectStateManager
            .GetObjectStateEntries(AddedAndModified);

        return entries.Where(e => e != null);
    }

    private static void Validate(IEnumerable<object> entities)
    {
        ValidationResults[] invalidResults = (
            from entity in entities
            let type = entity.GetType()
            let validator = ValidationFactory.CreateValidator(type)
            let results = validator.Validate(entity)
            where !results.IsValid
            select results).ToArray();

        if (invalidResults.Length > 0)
            throw new ValidationException(invalidResults);
    }    
} 

您可以阅读有关它的更多信息 这里

I'm personally not a fan of calling validation directly in code, and especially not directly on a entity itself. There will be a lot of places were you will call Validate and it is easy to forget to call Validate. Instead, let the ObjectContext invoke the underlying validation framework automatically for ALL entities that have changed, and throw a special exception (that can be caught in the presentation layer) when validation errors occur.

You can do this by hooking onto the ObjectContext.SavingChanges event and trigger validation there. You can write your partial ObjectContext as follows:

public partial class ModelContainer
{
    partial void OnContextCreated()
    {
        this.SavingChanges +=
            (sender, e) => Validate(this.GetChangedEntities());
    }

    private IEnumerable<object> GetChangedEntities()
    {
        const EntityState AddedAndModified =
            EntityState.Added | EntityState.Modified;

        var entries = this.ObjectStateManager
            .GetObjectStateEntries(AddedAndModified);

        return entries.Where(e => e != null);
    }

    private static void Validate(IEnumerable<object> entities)
    {
        ValidationResults[] invalidResults = (
            from entity in entities
            let type = entity.GetType()
            let validator = ValidationFactory.CreateValidator(type)
            let results = validator.Validate(entity)
            where !results.IsValid
            select results).ToArray();

        if (invalidResults.Length > 0)
            throw new ValidationException(invalidResults);
    }    
} 

You can read more about it here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文