Castle Active Record(Linq 和验证)问题

发布于 2024-09-05 03:24:12 字数 3413 浏览 4 评论 0原文

我正在尝试 Castle ActiveRecord。我想使用验证功能和 LINQ 功能。

为了使用 LINQ,您可以:

  1. 我的偏好:让您的实体继承自ActiveRecordLinqBase,然后查询:

    var blogs = (from b in Blog.Queryable select b).ToList();

  2. 使用ActiveRecordLinq.AsQueryable,例如:

    var blogs = (from b in ActiveRecordLinq.AsQueryable() select b).ToList()

现在,要使用验证功能,您必须使实体继承自 ActiveRecordValidationBase

不支持多重继承,因此,这是我的选择:

  1. 使用上面的#2,同时使我的实体继承自 ActiveRecordValidationBase。缺点:LINQ 语句更长且更难看。
  2. 创建一个继承 ActiveRecordLinqBase 的类,并复制 ActiveRecordValidationBase 中的代码。缺点:重复代码,必须使用未来的 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;
            }
        }
    }
}

有更好的办法吗?

I am trying out Castle ActiveRecord. I want to use the Validation features AND the LINQ features.

In order to use LINQ, you can either:

  1. My preference: Make your entities inherit from ActiveRecordLinqBase<T>, then to query:

    var blogs = (from b in Blog.Queryable select b).ToList();

  2. Use ActiveRecordLinq.AsQueryable<T>, e.g.:

    var blogs = (from b in ActiveRecordLinq.AsQueryable() select b).ToList()

Now, to use the validation features, you have to make your entities inherit from ActiveRecordValidationBase<T>.

Multiple inheritance isn't supported so, here's my options:

  1. Use #2 from above while making my entities inherit from ActiveRecordValidationBase<T>. Disadvantage: LINQ statements are longer and uglier.
  2. Create a class that inherits from ActiveRecordLinqBase<T> and duplicates the code found in ActiveRecordValidationBase<T>. Disadvantage: Duplicate code, which must be updated with future ActiveRecord releases. Here's the class:

Edit: 3. (Not Tested) Simulate multiple inheritance. Disadvantage: Have to keep Property and Method Definitions in sync with updates.

 

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;
            }
        }
    }
}

Is there a better way?

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

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

发布评论

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

评论(1

只为守护你 2024-09-12 03:24:12

要使用验证功能,您必须使实体继承 ActiveRecordValidationBase。

未必。验证是一个单独的 Castle 项目,它与 ActiveRecord 的耦合不是很紧密。您可以手动运行验证< /a>.我所说的手动是指将其包装在您自己的存储库/DAO 类中。

由于它是松散耦合的,您甚至可以选择任何其他验证框架。

就我个人而言,我不认为 ActiveRecordLinq.AsQueryable()Blog.Queryable 更长或更丑,所以我会选择该选项。

to use the validation features, you have to make your entities inherit from ActiveRecordValidationBase.

Not necessarily. Validation is a separate Castle project, it's not very tightly coupled to ActiveRecord. You can run the validation manually. By manually I mean wrapping this in your own repository/DAO class.

And since it's loosely coupled you could even choose any other validation framework.

Personally, I don't consider ActiveRecordLinq<Blog>.AsQueryable() to be much longer or uglier than Blog.Queryable so I'd go with that option.

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