Подтвердить этот подход к проверке EF4? - PullRequest
0 голосов
/ 07 декабря 2010

Я очень новичок в 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 есть конфигурация ZERO.

Как разрез моей стрелы? :)

Richard

1 Ответ

1 голос
/ 12 декабря 2010

Лично я не фанат вызова валидации непосредственно в коде, и особенно не непосредственно в самой сущности.Там будет много мест, где вы будете звонить 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);
    }    
} 

Подробнее об этом можно прочитать здесь .

...