亚音速 - 我在哪里包含我的业务逻辑或自定义验证

时间:2010-10-06 10:41:21

标签: subsonic subsonic3 subsonic2.2

我使用亚音速2.2

我试着用另一种方式问这个问题,但没有得到我正在寻找的答案。

基本上,我通常在页面级别或我的代码中包含验证,用于我的用户控件或aspx页面。然而,我看到一些小信息建议可以在亚音速生成的部分类中完成。

所以我的问题是,我在哪里放这些,是否有特定事件我将我的验证/业务逻辑添加到插入或更新等。 - 如果是,并且验证未得到满足,如何停止插入或更新。如果有人有一个代码示例,看起来如何开始我会很棒。

任何信息都非常感谢。

3 个答案:

答案 0 :(得分:1)

首先,您应该为要使用的DAL对象创建一个分部类。 在我的项目中,我有一个文件夹Generated,其中生成的类存在,我有另一个文件夹Extended

假设您有一个Subsonic生成的类Product。在您的Extended(或其他)文件夹中创建一个新文件Product.cs并创建一个部分类Product,并确保该命名空间与亚音速生成的类命名空间匹配。

namespace Your.Namespace.DAL
{
    public partial class Product
    {
    }
}

现在您可以扩展产品类。有趣的是,亚音速提供了一些覆盖的方法。

namespace Your.Namespace.DAL
{
    public partial class Product
    {

        public override bool Validate()
        {

            ValidateColumnSettings();

            if (string.IsNullOrEmpty(this.ProductName))
                this.Errors.Add("ProductName cannot be empty");

            return Errors.Count == 0;
        }

        // another way
        protected override void BeforeValidate()
        {
            if (string.IsNullOrEmpty(this.ProductName))
                throw new Exception("ProductName cannot be empty");
        }

        protected override void BeforeInsert()
        {
           this.ProductUUID = Guid.NewGuid().ToString();
        }

        protected override void BeforeUpdate()
        {
           this.Total = this.Net + this.Tax;
        }

        protected override void AfterCommit()
        {
            DB.Update<ProductSales>()
                  .Set(ProductSales.ProductName).EqualTo(this.ProductName)
                  .Where(ProductSales.ProductId).IsEqualTo(this.ProductId)
                  .Execute();
        }

    }
}

答案 1 :(得分:1)

回应丹的问题:

首先,请看一下:http://github.com/subsonic/SubSonic-2.0/blob/master/SubSonic/ActiveRecord/ActiveRecord.cs

在这个文件中存在我在其他帖子中展示的整个逻辑。

  • 验证:在Save()期间调用,如果Validate()返回false,则抛出异常。 只有在属性ValidateWhenSaving(这是一个常量,因此你必须重新编译SubSonic来改变它)才被调用(默认)

  • BeforeValidate:当ValidateWhenSaving为true时,在Save()期间调用。默认情况下不执行任何操作

  • BeforeInsert:如果记录是新的,则在Save()期间调用。默认情况下什么都不做。

  • BeforeUpdate:如果记录是新的,则在Save()期间调用。默认情况下什么都不做。

  • AfterCommit:在成功插入/更新记录后调用。默认情况下什么都不做。

在我的Validate()示例中,我首先运行默认的ValidatColumnSettings()方法,如果产品名称长于数据库中定义的值,则会添加“如ProductName列超出最大字符串长度”之类的错误。然后,如果ProductName为空,我会添加另一个errorstring,如果整体错误计数大于零,则返回false。

这将在Save()期间抛出异常,因此您无法将记录存储在数据库中。

我建议您自己调用Validate(),如果它返回false,则在页面底部显示this.Errors的元素(简单方法)或者(更优雅)创建Dictionary<string, string>其中键是列名,值是原因。

    private Dictionary<string, string> CustomErrors = new Dictionary<string, string>
    protected override bool Validate()
    {

        this.CustomErrors.Clear();
        ValidateColumnSettings();

        if (string.IsNullOrEmpty(this.ProductName))
            this.CustomErrors.Add(this.Columns.ProductName, "cannot be empty");

        if (this.UnitPrice < 0)
            this.CustomErrors.Add(this.Columns.UnitPrice, "has to be 0 or bigger");

        return this.CustomErrors.Count == 0 && Errors.Count == 0;
    }

然后,如果Validate()返回false,您可以直接在网页右侧字段的下方/下方添加原因。

如果Validate()返回true,你可以安全地调用Save(),但请记住,Save()可能会在持久性过程中抛出其他错误,如“Dublicate Key ...”;

答案 2 :(得分:0)

感谢您的回复,但是如果您验证validate()或beforevalidate()中的列(ProductName)值是字符串为空还是NULL,您是否可以为我确认这一点很困惑,这并不意味着插入/ update已经被操作了,否则它不会知道你试图从页面中的UI / aspx字段插入或更新空值到列?

另外,在asp.net插入或更新事件中,我们使用e.cancel = true来停止插入更新,如果beforevalidate failes会自动停止插入或更新操作吗?

如果是这种情况,那么添加页面级别验证以阻止首先触发插入或更新是不行的。

我想我对这些方法的生命周期以及它们发挥作用时会感到困惑