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

发布于 2024-09-26 11:19:02 字数 272 浏览 1 评论 0原文

我使用 subsonic 2.2

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

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

所以我的问题是,我应该把这些放在哪里,是否有我添加验证/业务逻辑的特定事件,例如插入或更新。 - 如果是这样,并且未满足验证,我如何停止插入或更新。如果有人有一个代码示例来说明它的外观,那么我会很好地开始。

任何信息都非常感谢。

Im using subsonic 2.2

I tried asking this question another way but didnt get the answer i was looking for.

Basically i ususally include validation at page level or in my code behind for my user controls or aspx pages. However i haev seen some small bits of info advising this can be done within partial classes generated from subsonic.

So my question is, where do i put these, are there particular events i add my validation / business logic into such as inserting, or updating. - If so, and validation isnt met, how do i stop the insert or update. And if anyone has a code example of how this looks it would be great to start me off.

Any info greatly appreciated.

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

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

发布评论

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

评论(3

(り薆情海 2024-10-03 11:19:02

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

假设您有一个 Subsonic 生成的类 Product。在扩展(或其他)文件夹中创建一个新文件 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();
        }

    }
}

First you should create a partial class for you DAL object you want to use.
In my project I have a folder Generated where the generated classes live in and I have another folder Extended.

Let's say you have a Subsonic generated class Product. Create a new file Product.cs in your Extended (or whatever) folder an create a partial class Product and ensure that the namespace matches the subsonic generated classes namespace.

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

Now you have the ability to extend the product class. The interesting part ist that subsonic offers some methods to override.

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

    }
}
岛歌少女 2024-10-03 11:19:02

回答 Dan 的问题:

首先,看看这里: http://github.com/subsonic/SubSonic-2.0/blob/master/SubSonic/ActiveRecord/ActiveRecord.cs

在这个文件中,包含了我在另一篇文章中展示的整个逻辑。

  • Validate:在 Save() 期间调用,如果 Validate() 返回 false,则会引发异常。
    仅当属性 ValidateWhenSaving(这是一个常量,因此您必须重新编译 SubSonic 才能更改它)为 true(默认)时才调用 Get

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

  • BeforeInsert:如果记录是新的,则在 Save() 期间调用。默认情况下不执行任何操作。

  • BeforeUpdate:如果记录是新的,则在 Save() 期间调用。默认情况下不执行任何操作。

  • AfterCommit:成功插入/更新记录后调用。默认情况下不执行任何操作。

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

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

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

    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 ...”;

In response to Dan's question:

First, have a look here: http://github.com/subsonic/SubSonic-2.0/blob/master/SubSonic/ActiveRecord/ActiveRecord.cs

In this file lives the whole logic I showed in my other post.

  • Validate: Is called during Save(), if Validate() returns false an exception is thrown.
    Get's only called if the Property ValidateWhenSaving (which is a constant so you have to recompile SubSonic to change it) is true (default)

  • BeforeValidate: Is called during Save() when ValidateWhenSaving is true. Does nothing by default

  • BeforeInsert: Is called during Save() if the record is new. Does nothing by default.

  • BeforeUpdate: Is called during Save() if the record is new. Does nothing by default.

  • AfterCommit: Is called after sucessfully inserting/updating a record. Does nothing by default.

In my Validate() example, I first let the default ValidatColumnSettings() method run, which will add errors like "Maximum String lenght exceeded for column ProductName" if product name is longer than the value defined in the database. Then I add another errorstring if ProductName is empty and return false if the overall error count is bigger than zero.

This will throw an exception during Save() so you can't store the record in the DB.

I would suggest you call Validate() yourself and if it returns false you display the elements of this.Errors at the bottom of the page (the easy way) or (more elegant) you create a Dictionary<string, string> where the key is the columnname and the value is the reason.

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

Then if Validate() returns false you can add the reason directly besides/below the right field in your webpage.

If Validate() returns true you can safely call Save() but keep in mind that Save() could throw other errors during persistance like "Dublicate Key ...";

枕花眠 2024-10-03 11:19:02

感谢您的回复,但是您能否帮我确认一下,因为我有点困惑,如果您在 validate() 或 beforevalidate() 中验证列 (ProductName) 值是字符串空或 NULL,这是否意味着插入/更新已已经采取行动,否则它不会知道您已尝试从页面内的 UI / aspx 字段插入或更新空值到列?

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

如果是这种情况,那么添加页面级验证以首先阻止插入或更新被触发不是更容易吗?

我想我对这些方法的生命周期以及它们何时发挥作用有点困惑

Thanks for the response, but can you confirm this for me as im alittle confused, if your validating the column (ProductName) value within validate() or the beforevalidate() is string empty or NULL, doesnt this mean that the insert / update has already been actioned, as otherwise it wouldnt know that youve tried to insert or update a null value from the UI / aspx fields within the page to the column??

Also, within asp.net insert or updating events we use e.cancel = true to stop the insert update, if beforevalidate failes does it automatically stop the action to insert or update?

If this is the case, isnt it eaiser to add page level validation to stop the insert or update being fired in the first place.

I guess im alittle confused at the lifecyle for these methods and when they come into play

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