Best way of saving associations and totals

Hi, still experimenting with Aurelius I´ve encountered myself with a question. Let´s suppose we have the following classes (simplified for example purposes):


    TSalesByDay = class;


    [Entity]
    [Automapping]
    TSale = class
    private
        fID: Integer;
        fTotal: Currency;
        [Association([TAssociationProp.Lazy, TAssociationProp.Required], [TCascadeType.SaveUpdate])]
        [JoinColumn('ID_SALEDAY', [TColumnProp.Required])]
        fSaleDay : Proxy<TSalesByDay>;
    public
        property ID: Integer read fID write fID;
        property Total: Currency read fTotal write fTotal;
        property SaleDay : TSalesByDay read fSaleDay;
    end;


    [Entity]
    [Automapping]
    TSalesByDay = class
    private
        fID: Integer;
        fDate: TDateTime;
        fTotalSold : Currency;
        [ManyValuedAssociation([TAssociationProp.Lazy], CascadeTypeAll, 'fSaleDay')]
        FSales: Proxy<TList<TSale>>;
    protected
        function GetSales() : TList<TSale>;
    public
        property ID: Integer read fID write fID;
        property Date: TDateTime read fDate write fDate;
        property TotalSold: Currency read fTotalSold;
        property Sales : TList<TSale> read GetSales;
    end;




In this case, what is the best method to save a new sale?:

Approach A:

TodaysSales := Manager.Find<TSalesByDay>(1);


NewSale := TSale.Create;
NewSale.Total := 100;
NewSale.SaleDay := TodaysSales;
Manager.Save(NewSale);


Approach B:

TodaysSales := Manager.Find<TSalesByDay>(1);


NewSale := TSale.Create;
NewSale.Total := 100;
TodaysSales.Sales.Add(NewSale); 
Manager.Save(TodaySales);


NOTE: Since sometimes there´s is A LOT of sales records I added the "TotalSold" property to the TSalesByDay class to obtain in the instant the total amount sold in that day, and also to perform queries such as "How much was sold in the past 3 years" in which I just query the TSalesByDay table/class instead of performing a SUM for all the TSale records.

So, my question is how to auto-sum / update the "TotalSold" property in the TSalesByDay class every time a new TSale is added to the list or saved to the database? (I want to do this: 


TodaySales.TotalSold := TodaySales.TotalSold + NewSale.Total;


But automatically everytime a new TSale is saved.

Any help/recommendations in the design of this classes would be appreciated.

Thanks in advance.

Hi Luis,


actually both approaches A and B are fine when it comes to the database persistence. Both will work ok. But if you want to make sure your objects in memory are filled correct, nothing prevent you from doing this (and you will have the collection filled correctly, and NewSale.SaleDay property filled correctly as well):


TodaysSales := Manager.Find<TSalesByDay>(1);
NewSale := TSale.Create;
NewSale.Total := 100;
NewSale.SaleDay := TodaysSales;
TodaysSales.Sales.Add(NewSale); 
Manager.Save(TodaySales);

about your approach for having the Total, well, I know you didn't ask this, but I feel that the idea is not very effective. What if some user changes the value of TSale.Total property? You will end up having inconsistent results. And maybe iterating through the collection is not that slow anyway.
My suggestion would be that you just use a GetTotalSold getter and in such method iterate through all items and sum their values. It will be "slower" when you need to read that property from the object, but it will be saved in a proper database field, and queries will still use that value for your reports (like total sold in last 3 months).

Hi Wagner, thank your for your answer. I´ve actually went for a "simpler" approach, just adding a new method to TodaySales class called "AddSale" which just sums the Total property correctly and avoids the problem you describe in which a user could change directly the "Total" property which in turn is converted to a read-only property.