Deep Copy (Clone) and resetting the primary keys

Posts   
 
    
rbrown
User
Posts: 36
Joined: 11-Jun-2008
# Posted on: 02-Dec-2010 19:18:49   

Hi,

I've written some generic code to deep clone an entity graph. I've used the memory stream trick as discussed here:

http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=7568

The cloning works, but when I try to save I get insert errors because of duplicate PKs. So I tried adding in code to change the PK fields, but I'm still unable to get it working.

My SQLServer database uses Guid (uniqueidentifier) PK fields in all tables, with default values of new guids. My application normally just creates entities without PK values and lets the database assign them - we use recursive saves and we've not had any problems with getting the new IDs back. So my first approach to the clone PK issue was to simply null out the PK fields, in hopes that the recursive Save would insert them as new ones and it would work like usual.

So I used

clone.Fields[pkIndex].ForcedCurrentValueWrite(null); 

as discussed here: http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=12800

This does in fact null out the PK field but when it tries to insert the new record, the insert statement actually tries to insert a null (as opposed to just omitting the PK field, allowing for a default to happen). Therefore I get insert error about a null PK.

I have tried changing it to

clone.Fields[pkIndex].ForcedCurrentValueWrite(Guid.NewGuid()); 

This gets me one step further, and the new guid is used, however the related entities in the graph are still using the old guid which means the persisted entities have the wrong FK values.

So I believe my issue could be solved in either approach if I could figure out one of these questions:

1) When setting the PK's to null, how can I tell the recursive save to omit the null PK field during insert? (somehow it does it for new entities created regularly, but I can't get the clones back into that state)

OR

2) When assigning a new PK guid, how can I cascade that through the entity graph to related entities so they have the correct new FK value?

Any help would be greatly appreciated! Thanks, Randy

LLBLGen 2.6 Final Adapter Model SQL Server 2008 R2 .NET 4.0

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 03-Dec-2010 04:31:27   

Hi Randy,

That should works following these stepts:

  1. Fetch the entity graph.
  2. Clone the entity graph.
  3. Set the new PK. Here LLBLGen performs PK-FK synchronization, so all children of the root entity should be actualized.
  4. Save it back recursively

Example:

// load some graph
PrefetchPath path = new PrefetchPath((int)EntityType.CustomerEntity);
path.Add(CustomerEntity.PrefetchPathOrders);
CustomerEntity customer = new CustomerEntity("ALFKI", path);

// create a cloned graph
CustomerEntity newCustomer = (CustomerEntity) xyz.CloneHelper.CloneEntity(customer);

// this is my new customer
newCustomer.CustomerId = "YUJU";

// save the whole graph
newCustomer.Save(true);

If you are getting something different please: - Post your real code - Describe your entity graph - Post the exception message and stack trace - Post the generated SQL of the save action.

David Elizondo | LLBLGen Support Team