Reset Identity Field

Posts   
 
    
Ian avatar
Ian
User
Posts: 511
Joined: 01-Apr-2005
# Posted on: 25-Mar-2009 13:45:55   

Hi there,

I would like to re-save an entity instance as a new instance. The entity instance has an identity column value set as a result of its initial save. How can I reset this column so that its given a new value by the database and treated as an insert by LLBLGen? All the other fields should retain their original value.

Cheers, Ian.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 25-Mar-2009 14:40:55   

Set entity.IsNew to true, and then Save.

Ian avatar
Ian
User
Posts: 511
Joined: 01-Apr-2005
# Posted on: 15-May-2009 14:08:02   

It doesn't seem to be as simple as that. When I re-save the entity instance after setting 'IsNew' to true, the db is complaining about a missing value.

The error is...

Cannot insert the value NULL into column 'ProductID', table 'bangfaceweekender.dbo.tbl_order_detail'; column does not allow nulls.

If I don't set 'IsNew' to true then this doesn't happen.

rdhatch
User
Posts: 198
Joined: 03-Nov-2007
# Posted on: 15-May-2009 16:33:33   

Hi Ian,

I've been through all of those problems myself.

When I do it, I create an entirely new entity and loop through all the fields and copy everything over but the Primary Key fields (look for myField.IsPrimaryKey).


    ''' <summary>
    ''' Simply Clones a single entity as new.  Just fields are cloned, not related entities
    ''' </summary>
    ''' <typeparam name="TEntity"></typeparam>
    ''' <param name="myEntity"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function CloneSingleEntityAsNew(Of TEntity As EntityBase)(ByVal myEntity As TEntity) As TEntity
        'Get Entity Factory
        Dim myFactory As IEntityFactory = myEntity.GetEntityFactory

        'Create New Entity used as Clone (Serialization is not used because Primary Key cannot be cleared)
        Dim newEntity As TEntity = myFactory.Create()

        'Or could we use ForcedCurrentValueWrite(Nothing) to reset PrimaryKey on a Serialized Clone?

        'Copy all Fields
        For Each newField As EntityField In newEntity.Fields
            'Ignore Primary Key
            If newField.IsPrimaryKey = False And newField.IsReadOnly = False Then
                'Copy Value to Clone
                newField.CurrentValue = myEntity.Fields(newField.Name).CurrentValue
                newField.IsChanged = True
            End If
        Next

        newEntity.IsDirty = True
        newEntity.Fields.IsDirty = True

        Return newEntity
    End Function

Please let me know if the RecursiveCloneAsNew() function, which is much more extensive, would be helpful to you.

Ryan

Ian avatar
Ian
User
Posts: 511
Joined: 01-Apr-2005
# Posted on: 16-May-2009 15:59:16   

Yes, that would be interesting to see. sunglasses

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 18-May-2009 07:34:00   

It doesn't seem to be as simple as that. When I re-save the entity instance after setting 'IsNew' to true, the db is complaining about a missing value.

The error is...

Quote: Cannot insert the value NULL into column 'ProductID', table 'bangfaceweekender.dbo.tbl_order_detail'; column does not allow nulls.

If I don't set 'IsNew' to true then this doesn't happen.

LLBLGen Pro only attempt to save changed fields. So if you are using an already saved entity and you want to insert it again, then you should loop on its fields and set each field IsChanged property to true, also set the entity.IsDirty field to true.

rdhatch
User
Posts: 198
Joined: 03-Nov-2007
# Posted on: 18-May-2009 09:01:23   

Hi Walla -

Thanks for the reply. Some PrimaryKey fields as well as other fields may be ReadOnly. So I could either use ForceCurrentValueWrite on a serialized clone or just create a new entity & copy the fields. Up until now, I decided to create a new entity to do the clone.

However, because I'm using OnInitialized() to define default Entity values (and now even creating default child entities, as well) - creating a new entity could also create new child entities that you do NOT want cloned. So, I think I'm going to opt for ForceCurrentValueWrite() on a serialized clone.

I haven't tried this route yet. Do you think ForceCurrentValueWrite(Nothing) & .isChanged = True on the Primary Key fields would do an INSERT & return a new Identity/NewSequentialId?

Thanks for the feedback. Always improving. wink

Ryan

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 18-May-2009 15:12:07   

What llblgen pro runtime library version are you using?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 19-May-2009 10:54:50   

INSERTING a new value in an identity column means that you want to save a NEW entity. If you have an existing entity class instance, you can achieve that by setting the IsNew to true, the entity.Fields.State to New, and make sure some values in the entity object are indeed set so there's something to save.

Though it's recommended that you create a new entity class instance and save that: entity class instances are often placed in graphs so are related to other entities and this easily creates problems if you start setting Isnew flags to true again.

Frans Bouma | Lead developer LLBLGen Pro
Ian avatar
Ian
User
Posts: 511
Joined: 01-Apr-2005
# Posted on: 20-May-2009 04:42:00   

INSERTING a new value in an identity column means that you want to save a NEW entity.

Oh yes... a bit like changing the primary key of a row in the database. Probs shouldn't do that.

rdhatch
User
Posts: 198
Joined: 03-Nov-2007
# Posted on: 20-May-2009 05:20:54   

Thanks, Frans. I'll stick with the method I've outlined above for cloning a single entity.

Ryan

PS. Your nickname always screws me up. I almost called you Otis! wink