Is it possible to recheck just the broken rules?

Is it possible to recheck just the broken rules?

Old forum URL: forums.lhotka.net/forums/t/5389.aspx


rsbaker0 posted on Thursday, September 11, 2008

The subject pretty much says it all.

Is there a reasonable strategy for just rechecking rules that are broken versus all the rules?

(It's a performance question more than anything. We have business rules that may access the database, so checking rules known to be OK is not something we would prefer to do)

simon_may replied on Thursday, September 11, 2008

I would imagine that state management in your object would become a difficult issue.

rsbaker0 replied on Thursday, September 11, 2008

Hmmmm. OK, maybe this isn't a good idea. (And generally, I have avoided short-circuiting in validation rules but instead coded the rules so they don't do anything if they happen to be critically dependent on some property checked in a prior rule)

I actually managed to code around this by changing the order of the operations I was doing.

We're porting to CSLA/C# from a legacy Visual C++ 6.0 application, and our new framework enforces referential integrity at the time you set the property value for the foreign key reference.

So, I just re-ordered the actual data access calls themselves to ensure that I didn't reference an object key before actually writing that object to the database. (Probably a good idea anyway -- in fact most databases would enforce this if the constraints were actually in the database)

I could also have rechecked all the rules just before writing the "temporarily" broken object, but I was just wondering about the feasibility of just retrying the broken ones.

SonOfPirate replied on Friday, September 12, 2008

Obviously this is possible but there are other conditions that you would have to code for.  We've implemented a flag to indicate that an object has previously been validated so that we don't incur the performance hit of repeated validation calls.  We had to add a line when a property is changed to clear this flag so that validation will run again with the new value(s).  It would certainly be possible to do something similar so that only the first call validates all of the rules and any subsequent call only rechecks rules that were previously broken.  But, why would you want to do this?

Where I see the problem is the reason you are checking the rules again is because something changed in your object.  Who's to say that another rule didn't break as a result of the change?  If you don't recheck them all, you will never know this.

While it is possible, I don't see a good reason to go down this path.  I agree with the previous posts, find a way to use the priority, severity and shortcutting features to accomplish what you want.

HTH

 

rsbaker0 replied on Friday, September 12, 2008

SonOfPirate:

...Where I see the problem is the reason you are checking the rules again is because something changed in your object.  Who's to say that another rule didn't break as a result of the change?  If you don't recheck them all, you will never know this...

Actually, what changed was something outside the object, the presence of a related object in the database.

I had set a foreign key value in an object before writing the primary object. Our validation rules break the object if you set a foreign key that doesn't exist in the database.

So the object is sitting there broke, and now I write the primary record to the database. The object is now (in theory) valid, even though I didn't change it.

Admittedly, this was a weird case, and I corrected the problem by changing the order of operations, but I had wondered whether you could run specific rules rather than all of them.

(When we get to production, we'll almost certainly have a performance option to suspend checking of foreign key rules in transactions, but it's nice to see the framework flagging our own transgressions... :)

 

 

rsbaker0 replied on Saturday, September 13, 2008

Followup: It's actually trivial to recheck all the rules for broken properties. Can anyone think of why the code below would necessarily cause problems?

        /// <summary>
        /// Recheck rules for broken properties
        /// </summary>
        public virtual void RecheckRules()
        {
            List<string> brokenProperties = new List<string>();
            foreach (BrokenRule br in this.BrokenRulesCollection)
            {
                if (!brokenProperties.Contains(br.Property))
                    brokenProperties.Add(br.Property);
               
            }

            foreach (string prop in brokenProperties)
            {
                ValidationRules.CheckRules(prop);
            }
        }

simon_may replied on Sunday, September 14, 2008

All is well provided that you can guarantee that in fixing those broken rules you have not broken any rules that were not broken thus leaving your object invalid and now not knowing about it.

I can understand why it is tempting. but it has to be a dangerous strategy. Priorities and shortcircuiting must be the way to go

rsbaker0 replied on Sunday, September 14, 2008

simon_may:

...Priorities and shortcircuiting must be the way to go

You might look at this thread:

http://forums.lhotka.net/forums/thread/20227.aspx

It turns out the priorities and short-circuiting only work well within a single property and you can't strictly enforce order across properties (e.g. when you have dependencies)

 

Fintanv replied on Thursday, September 11, 2008

Would rule priorities help to cushion the performance issues?  Database rules should run only if other (faster) rules have not been broken.

Copyright (c) Marimer LLC