Recursive delete , change pk and then save as new

Posts   
 
    
BlackMamba avatar
BlackMamba
User
Posts: 34
Joined: 30-Apr-2004
# Posted on: 30-Mar-2005 19:10:48   

Hi, I'm trying to do this (without success): I have one entity which has multiple 1:n relations and I need to modify a primary key field on the entity and on all related entities.

The db could do this for me but I want to do it in code for various reasons. What I'm doing is deleting all related entities and then the main one, after that I change the pk field in question on all relevant entities while also setting IsNew = true for them, and then I try to save.

It doesn't work , saving the entity modified like this LLBLGen tries to insert nulls into the database (well this is the error I get now) but the entity has correct values in it (fetched previously to carry out the delete).

Anyhow I looked through documentation to understand how this can be done but cannot find a way out, some help will be appreciated..

Thanks a lot Simone

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 31-Mar-2005 12:25:09   

Could you please paste some code what you tried?

Updating PK values can be done, but not in recursive saves. You also have to fetch the entity, then change the PK value and then save it again.

Frans Bouma | Lead developer LLBLGen Pro
BlackMamba avatar
BlackMamba
User
Posts: 34
Joined: 30-Apr-2004
# Posted on: 31-Mar-2005 22:19:06   

Otis wrote:

Could you please paste some code what you tried?

Updating PK values can be done, but not in recursive saves. You also have to fetch the entity, then change the PK value and then save it again.

Sure, here is what I do:


Public Sub SpostaPraticheUtente(ByVal sourceUserId As String, ByVal destinationUserId As String)
    Dim checkLists As EntityCollection = CheckListManagement.FetchCollectionForUser(sourceUserId)
    Try
        adapter.StartTransaction(IsolationLevel.Unspecified, "SPU")
        For Each cl As MyCheckListEntity In checkLists
            adapter.DeleteEntityCollection(cl.AttAltro)
            adapter.DeleteEntityCollection(cl.AttDepositoCommercioIngrosso)
            adapter.DeleteEntityCollection(cl.AttLaboratorioProdTrasformazione)
            adapter.DeleteEntityCollection(cl.AttProduzionePrimaria)
            adapter.DeleteEntityCollection(cl.AttRistorazione)
            adapter.DeleteEntityCollection(cl.AttVenditaAlDettaglio)
        Next
        adapter.DeleteEntityCollection(checkLists)
        ChangeUserIdOnAllEntitiesAndMarkAsNew(checkLists, destinationUserId)
        For Each cl As MyCheckListEntity In checkLists
            ChangeUserIdOnAllEntitiesAndMarkAsNew(cl.AttAltro, destinationUserId)
            ChangeUserIdOnAllEntitiesAndMarkAsNew(cl.AttDepositoCommercioIngrosso, destinationUserId)
            ChangeUserIdOnAllEntitiesAndMarkAsNew(cl.AttLaboratorioProdTrasformazione, destinationUserId)
            ChangeUserIdOnAllEntitiesAndMarkAsNew(cl.AttProduzionePrimaria, destinationUserId)
            ChangeUserIdOnAllEntitiesAndMarkAsNew(cl.AttRistorazione, destinationUserId)
            ChangeUserIdOnAllEntitiesAndMarkAsNew(cl.AttVenditaAlDettaglio, destinationUserId)
        Next
        adapter.SaveEntityCollection(checkLists)
        adapter.Commit()
    Catch ex As Exception
        adapter.Rollback()
        Throw New JessicaBLException(ex.Message, ex)
    End Try
End Sub

Private Sub ChangeUserIdOnAllEntitiesAndMarkAsNew(ByVal coll As EntityCollection, ByVal userId As String)
    For Each e As IEntity2 In coll
        e.SetNewFieldValue("UserId", userId)
    Next
End Sub

As you can see I have a collection of entities , each one has a series of properties with collections of related entities. So, starting from the root entity down I need to update one of the primary key fields. So I thought I would fetch all the data I need, delete all of it, then change the primary key value, and re-add the data with the new value but when I re-add the data an exception is thrown because NULLs are being inserted in the db.

Thanks Frans

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 01-Apr-2005 12:25:38   

Something like this should do:


Private Sub ChangeUserIdOnAllEntitiesAndMarkAsNew(ByVal coll As EntityCollection, ByVal userId As String)
    For Each e As IEntity2 In coll
        e.IsNew = True
        e.Fields.State = EntityState.New
        e.Fields.IsDirty = True
        For Each field As IEntityField2 In e.Fields
            field.IsChanged = (Not field.CurrentValue Is Nothing)
        Next
    Next
End Sub

Though you could (if your RDBMS supports it) use a cascading update clause on the FK defining the relation in the database. So if you change the PK field, it is cascaded through the graph for you by the database engine

Frans Bouma | Lead developer LLBLGen Pro