Проблема с активной записью замка (Linq AND Validation) - PullRequest
1 голос
/ 07 июня 2010

Я пробую Замок ActiveRecord. Я хочу использовать функции проверки и функции LINQ.

Чтобы использовать LINQ , вы можете:

  1. Мои предпочтения: заставить ваши объекты наследовать от ActiveRecordLinqBase<T>, а затем запросить:

    var blogs = (из b в Blog.Queryable выберите b) .ToList ();

  2. Использование ActiveRecordLinq.AsQueryable<T>, например ::

    var blogs = (из b в ActiveRecordLinq.AsQueryable () выберите b) .ToList ()

Теперь, чтобы использовать функции проверки, вы должны заставить свои объекты наследовать от ActiveRecordValidationBase<T>.

Множественное наследование не поддерживается, поэтому вот мои варианты:

  1. Используйте # 2 сверху, чтобы мои объекты наследовали от ActiveRecordValidationBase<T>. Недостаток: операторы LINQ длиннее и страшнее.
  2. Создайте класс, который наследуется от ActiveRecordLinqBase<T> и дублирует код, найденный в ActiveRecordValidationBase<T>. Недостаток: дубликат кода, который должен быть обновлен в будущих выпусках ActiveRecord. Вот класс:

Редактировать: 3. (Не проверено) Имитировать множественное наследование. Недостаток: необходимо синхронизировать определения свойств и методов с обновлениями.

using System;
using System.Collections;
using System.Xml.Serialization;
using Castle.ActiveRecord.Framework;
using Castle.Components.Validator;
using NHibernate.Type;

namespace Castle.ActiveRecord.Linq
{
    [Serializable]
    public abstract class ActiveRecordValidationLinqBase<T> : ActiveRecordLinqBase<T>, IValidationProvider where T : class
    {
        // Fields
        [NonSerialized]
        private IValidationProvider _actualValidator;

        // Methods
        protected ActiveRecordValidationLinqBase() { }

        protected override bool BeforeSave(IDictionary state)
        {
            if (!this.IsValid(RunWhen.Insert))
            {
                this.OnNotValid();
            }
            return base.BeforeSave(state);
        }

        public virtual bool IsValid()
        {
            return this.ActualValidator.IsValid();
        }

        public virtual bool IsValid(RunWhen runWhen)
        {
            return this.ActualValidator.IsValid(runWhen);
        }

        protected override bool OnFlushDirty(object id, IDictionary previousState, IDictionary currentState, IType[] types)
        {
            if (!this.IsValid(RunWhen.Update))
            {
                this.OnNotValid();
            }
            return base.OnFlushDirty(id, previousState, currentState, types);
        }

        protected virtual void OnNotValid()
        {
            ActiveRecordValidator.ThrowNotValidException(this.ValidationErrorMessages, this.PropertiesValidationErrorMessages);
        }

        // Properties
        [XmlIgnore]
        protected virtual IValidationProvider ActualValidator
        {
            get
            {
                if (this._actualValidator == null)
                {
                    this._actualValidator = new ActiveRecordValidator(this);
                }
                return this._actualValidator;
            }
        }

        [XmlIgnore]
        public virtual IDictionary PropertiesValidationErrorMessages
        {
            get
            {
                return this.ActualValidator.PropertiesValidationErrorMessages;
            }
        }

        public virtual string[] ValidationErrorMessages
        {
            get
            {
                return this.ActualValidator.ValidationErrorMessages;
            }
        }
    }
}

Есть ли лучший способ?

1 Ответ

3 голосов
/ 08 июня 2010

чтобы использовать функции проверки, вы должны заставить свои объекты наследоваться от ActiveRecordValidationBase.

Не обязательно. Валидация - это отдельный проект Castle, он не очень тесно связан с ActiveRecord. Вы можете запустить проверку вручную . Под ручным я подразумеваю оборачивание этого в ваш собственный репозиторий / класс DAO.

И поскольку он слабо связан, вы можете даже выбрать любую другую платформу проверки.

Лично я не считаю ActiveRecordLinq<Blog>.AsQueryable() намного длиннее или страшнее, чем Blog.Queryable, поэтому я бы выбрал этот вариант.

...