Unit Of Work - Iteration

Posts   
 
    
Bashar
User
Posts: 108
Joined: 11-Nov-2004
# Posted on: 17-Feb-2010 16:27:04   

Hi all, been so long since I last came here simple_smile

I'm facing a strange thing here, I know it has to do with caching and I'm almost sure I'm doing something wrong.

I'm creating a simple bookkeeping application where a user enters a set of accounts in a grid with a value adjacent to each account. The system then iterates through all the rows in the grid (or the bound entity collection) and updates the account balance; which is equal to the old balance + the new value.

What's happening is, if the user enters the same account in more than one row, only the value in the second instance is updated correctly.

Here's the code:

        Dim uow As New UnitOfWork
        Dim gc As New GeneralLedgerCollection
        gc.GetMulti(GeneralLedgerFields.StrGeneralLedgerId = Me.CurrentEntity.StrGeneralLedgerId)

        For Each detail As GeneralLedgerEntity In gc
            'Update account balances
            Dim ae As New AccountEntity(detail.StrAccountId)
            ae.DecTotalCredit += detail.DecDebit
            ae.DecTotalDebit += detail.DecCredit

            uow.AddForSave(ae)
        Next

What's going on here? simple_smile

Version: 2.6 Final Released On: June 6th, 2008

Thank you all in advance.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 18-Feb-2010 04:08:03   

Hi Bashar,

Welcome back to forums wink

I'm not sure to understand 100% your problem. In your snippet I guess you are reproducing what you do when iterate the grid rows. Now I suppose that in the loop the detail.StrAccountId appears more than once for the same value (for instance, the AccountId "245" is present in two details. Due to that you are adding for save twice the same entity, with different DecTotalCredit and DecTotalDebit values. Then the uow.Commit updates the two instances but of course the second overrides the first one. Is that what is happening?, if not please elaborate a bit more on that.

David Elizondo | LLBLGen Support Team
Bashar
User
Posts: 108
Joined: 11-Nov-2004
# Posted on: 18-Feb-2010 06:26:05   

Yes, that is pretty much it. Is this not how I am supposed to do it?

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 18-Feb-2010 09:49:13   

Same as David. I'm not sure I'm following you here.

If the user enters the same acount more than once, and hence you add the same entity twice to the UoW with different values to be set.

So 2 Updates are issued, and naturaly the second overwrites the first.

I think we must be missing something obvious here. The question is: how differently do you want the logic to behave?

Bashar
User
Posts: 108
Joined: 11-Nov-2004
# Posted on: 18-Feb-2010 10:13:53   

simple_smile I'd like both entities to be actioned.

For example, if account '245' is entered twice, once with the value 12 and then with a value of 10, I'd like the effect to the balance to be 12 + 10 = 22. Right now, I'm getting the effect of 10 only.

If this is the wrong way to do it, what's the right way?

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 18-Feb-2010 10:57:42   

Oh I see.

Dim ae As New AccountEntity(detail.StrAccountId)

The above line fetches the entity from the database, and so the debit/credit additions are done to the values fetched from the database, rather than on the previously processed values.

What you should do is: use a collection to save processed entities, and inside the loop, you should first check if the current entity, has been already added to the collection, and if so, you should fetch it from the collection and do your calculations (add the values) on its fields, otherwise you should fetch it from the database. And then outside the loop you should add this collection to the UoW to be saved.

Pseudocode:

        Create a collection X to hold the entities in memory.

        Loop on the GeneralLedgerEntities
            if the collection X has an entity with PK == detail.StrAccountId
                        Grab the entity Y from the collection.
            else 
                        fetch the entity Y from the database.
                        set someFlag to true.
            End if

            Process entity Y
            if someFlag = true
                        add entity Y to collection X
            End if
        Next

        Add collection X to UoW.