Need refresher... Rule Across Multiple Properties

Need refresher... Rule Across Multiple Properties

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


reagan123 posted on Wednesday, October 17, 2012

Hello,

I'm having a senior moment and can't seem to figure out how to handle the following.

My business object has 4 properties.

propW
propX
propY
propZ

I need to write a rule that checks that the sum of the 4 properties cannot exceed 24.  I know there is the Dependency, but I'm not sure how to set everything up for this scenario.

Any suggestions greatly appreciated.

Curelom replied on Wednesday, October 17, 2012

Try something like this.  It can be fleshed out a little more, but the basic idea is there.

    public class TotalSumMyObjectColumnsRule : BusinessRule {
        public TotalSumMyObjectColumnsRule(Csla.Core.IPropertyInfo primaryProperty, Csla.Core.IPropertyInfo[] secondaryProperties)
            : base(primaryProperty) {
            InputProperties = new List<Csla.Core.IPropertyInfo> { primaryProperty };
            InputProperties.AddRange(secondaryProperties);
        }

        protected override void Execute(RuleContext context) {
            MyObject target = context.Target as MyObject;
            if (target != null) {
             
           
                MyObjectList targetList = target.Parent as MyObjectList;
                if (targetList != null) {
                  var sum = context.InputPropertyValues.Select(o => (double)o.Value).Where(object => o.Key != PrimaryProperty).Sum();
                  //if there is a match, then error
                  if (sum > 24) {                       
                        context.AddErrorResult(PrimaryProperty,
                          "Total sum is The combination cannot exceed 24");
                    }
                }
            }           
        }
    }

reagan123 replied on Wednesday, October 17, 2012

Thank you.  That definitely appears that it will do the trick.  I'll try it out once I get back to my code.  What would the AddRule look like? 

I appreciate the help.

Curelom replied on Wednesday, October 17, 2012

BusinessRules.AddRule(

 

 

new TotalSumMyObjectColumnsRule(MyPrimaryProperty, new Csla.Core.IPropertyInfo

[] {propXProperty, propYProperty, propZProperty}));

JonnyBee replied on Thursday, October 18, 2012

There's a couple of possible bugs in the previous posts (f.ex: you cannot set the error message on one of the summary fields as the PrimaryProperty is excluded from the sum).

My preference is like this:

    public class SumMax<T> : BusinessRule where T : IComparable
    {
        public T Max { getprivate set; }
        public SumMax(IPropertyInfo primaryProperty, T max, params IPropertyInfo[] inputProperties)             : base(primaryProperty)         {             Max = max;             InputProperties = new List<IPropertyInfo>();             InputProperties.AddRange(inputProperties);         }         protected override void Execute(RuleContext context)         {             // Use linq Sum to calculate the sum value              var sum = context.InputPropertyValues.Sum(property => (dynamic)property.Value);             if (Max.CompareTo(sum)  > 0)                 context.AddErrorResult(string.Format("Sum cannot exceed {0}", Max));          }     }

Usage:
    BusinessRules.AddRule(new SumMax<decimal>(Num1Property, 24,
Num1Property
Num2PropertyNum3PropertyNum4Property));

Curelom replied on Thursday, October 18, 2012

Nice solution.  I like it.

reagan123 replied on Thursday, October 18, 2012

Thanks both of you.  I think either solution could work, but have ended up using the second approach.  I appreciate it.

Copyright (c) Marimer LLC