Delete entity inside collection

Posts   
 
    
JimFoye avatar
JimFoye
User
Posts: 656
Joined: 22-Jun-2004
# Posted on: 18-Feb-2005 00:38:55   

My POEnity class has a related collection PODetail, which I prefetch. I need to delete one of the detail items. How do I flag it so that when I call SaveEntity(..., true) the detail record gets deleted from the db? Or is this not going to be so elegant? Boy, I miss the self-servicing so much already. cry

jeffreygg
User
Posts: 805
Joined: 26-Oct-2003
# Posted on: 18-Feb-2005 01:47:48   

JimFoye wrote:

My POEnity class has a related collection PODetail, which I prefetch. I need to delete one of the detail items. How do I flag it so that when I call SaveEntity(..., true) the detail record gets deleted from the db? Or is this not going to be so elegant? Boy, I miss the self-servicing so much already. cry

Hi, Jim. It's funny, but we're both working on Purchase Order systems right now. simple_smile Regarding your question; UnitOfWork is your friend here as you can create a PODetailDeleteBucket to which you add PODetail entities that you want deleted, then you add that bucket to the UnitOfWork using UnitOfWork.AddCollectionForDelete.

The problem is that it's a bit of a pain tracking what's getting deleted, etc. So, I've built a "State Machine" that basically tracks actions made against collections for you and does the heavy lifting. It's more oriented toward datarows/tables as most of my subcollections are rendered as datatables to deal with multi-entity display issues, but it could be easily adapted for use directly with entities.

Basically, you instantiate the machine and provide the datasource. Then, you tell it to start tracking and from then on whatever you add, update, or delete from the machine automatically gets tracked and can be pulled out as collections (datarows, in my case) independently. Here's some code:


Dim detailStateMachine as StateMachine
Dim detailTable as DataTable
Dim uow as UnitOfWork2

'Instantiation
detailTable = _service.GetPODetailByPOID(pOID)
detailStateMachine = new StateMachine(detailTable)
uow = New UnitOfWork2

'Instructs the machine that all actions taken heretofore must be tracked
detailStateMachine.StartTracking()

'Pseudo-code follows
detailStateMachine.Add(key, data)
detailStateMachine.Update(key, data)
detailStateMachine.Delete(key)

'Data in each "State" can be pulled out independently
uow.AddCollectionForDelete(detailStateMachine.GetData(StateType.ToDelete))
uow.AddCollectionForSave(detailStateMachine.GetData(StateType.ToAdd))
uow.AddCollectionForSave(detailStateMachine.GetData(StateType.Persisted))

uow.Commit(myAdapter,True)

If you want the code, let me know. I've found that it works fantastically and my grids and sub-collections management dev time has shrunk dramatically - and I really hate managing all of that stuff manually, if you know what I mean.

Jeff...

<Edit> Changed two of the .AddCollectionForDelete() commands to .AddCollectionForSave()

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 18-Feb-2005 09:36:28   

Sounds like a great utility class, Jeff! simple_smile

I hope to update the UoW classes soon so they're much less pain to work with. The question about versioning is still open, it will take much more time to solve that though...

Frans Bouma | Lead developer LLBLGen Pro
JimFoye avatar
JimFoye
User
Posts: 656
Joined: 22-Jun-2004
# Posted on: 18-Feb-2005 15:21:20   

Ah, I confess I hadn't even looked at the unit of work class, thanks for pointing that out. Let me get my mind around that and then I'll take a closer look at your state machine.

Thanks.

jeffreygg
User
Posts: 805
Joined: 26-Oct-2003
# Posted on: 18-Feb-2005 20:02:58   

JimFoye wrote:

Ah, I confess I hadn't even looked at the unit of work class, thanks for pointing that out. Let me get my mind around that and then I'll take a closer look at your state machine.

Thanks.

Good enough. Just let me know.

BTW, if anyone's interested I've created a complete solution for rendering subcollections as datatables to deal with GUI display issues, multi-entity data issues, and what not, and then getting them back to entities and entity collections. The problem with using strict Entity Collections in the GUI tier is that most of the time (at least for me) you need to display data from multiple entities, not just one.

So, in the PO Line Item example, in a normalized database, the Line Item and the Inventory Item are in separate tables. However, in the grid you want to display both to the user. Simply databinding to a PO Line Item Entity Collection won't work because there's no way to display the related Inventory Item entity.

Enter the Dynamic List. The new(er) ResultsetFields functionality in LLBLGen Pro gives you the ability to construct a custom SELECT statement against the tables you need and return a datatable.

That's easy enough; the painful part is having to track actions (adds, updates, and deletes) against that data then getting the data back into entities and entity collections in order to save the information back to the database. What I've done is put together a system that allows one to get from the datarow all the way to a UnitOfWork and into the proper slots for saving or deleting.

If anyone's interested in working through a relatively complex solution to these issues let me know; I've put one together that, once you figure out how it works, is very simple to use.

The major parts of the system are:

  1. DisplayCollectionDefinition (defines a complete set of instructions on how to create a specific Dynamic List, including fields, sort clauses, group fields, criteria, etc. I use this to pass to my data service which fetches the typed list for me)

  2. DisplayCollectionDefinitionFactory (builds and returns Definitions based on a given Entity Type or Need and Context)

  3. StateMachine (already explained above. Tracks actions against datarows and moves data into the appropriate buckets for later retrieval)

  4. StateMachineExtractor (extracts and converts data from datarows into entities using delegates for the conversion mechanism)

  5. UnitOfWorkCreator (works with the StateMachineExtractor and adds in the collections returned from it into the appropriate slots in the UnitOfWork)

Jeff...

<Edit> This is for Adapter only...

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 19-Feb-2005 10:54:15   

If you want, Jeff, I can put it up the 3rd party section. It sounds like a great addition.

In the upcoming upgrade I'll add better functionality to the unitofwork classes. During the beta I hope users will give feedback on these if these are the right features or if they don't work and others are needed. simple_smile . Just 9 days to go to the deadline (I'll probably not finish it all before that date so make it 2 weeks)

Frans Bouma | Lead developer LLBLGen Pro
jeffreygg
User
Posts: 805
Joined: 26-Oct-2003
# Posted on: 21-Feb-2005 09:43:56   

Otis wrote:

If you want, Jeff, I can put it up the 3rd party section. It sounds like a great addition.

Sure. simple_smile Let me generalize a few things first as I've strongly typed a few things that won't be helpful to most, and I'll add some docs and a dummy frontend to demonstrate usage. I'll email it to you when ready.

Jeff...

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 21-Feb-2005 10:59:14   

great! thanks! simple_smile

Frans Bouma | Lead developer LLBLGen Pro