How I'm creating a duplicate copy / clone of an existing Entity

Posts   
 
    
Posts: 14
Joined: 14-Jan-2009
# Posted on: 17-Jul-2010 00:13:31   

Howdy folks,

Been reading a lot on the forums about .Clone() and creating copies of existing objects as entirely new entities that are saved as new records in the persistent storage. My use case regards taking a customer's default billing and/or shipping address and creating a copy of these AddressEntity objects to store permanently as the shipping address for a specific order. It's a simple copy of a simple object.

I don't have any questions, I just wanted to share my example (and code) in case it can be of service to anyone. A few things that were tricky were the (!address.Fields[i].IsPrimaryKey), the .IsNew and .IsDirty, and the fact that you have to .Save() the new entity before it can be used (obviously, it turns out).

In this case, I have a UserControl that handles display and editing of addresses, and I send it an AddressEntity via a public property called "Address."


// UserControl's ID is "BillingAddress"
BillingAddress.Address = AddressHelper.DuplicateAddress(Customer.BillingAddress);

In my AddressHelper.cs class, I have the following static method:


    public static AddressEntity DuplicateAddress(AddressEntity address)
    {
        // Create a new entity object
        AddressEntity newAddress = new AddressEntity();

        // For all of the fields except the PK, copy the field values one by one to the new entity
        for (int i = 0; i < address.Fields.Count; i++)
        {
            if (!address.Fields[i].IsPrimaryKey)
            {
                newAddress.Fields[i] = address.Fields[i];  // copy the value
                newAddress.Fields[i].IsChanged = true;   // specify that values have changed in the new object
            }
        }
        newAddress.IsNew = true;                           // specify that the object is new, i.e. generate a new persistent object/db entry
        newAddress.IsDirty = true;                       // specify that things have changed
        newAddress.Save();                               // save the new object in the persistent storage

        return newAddress;
    }

I suppose this could be made general purpose for any IEntity, but this is all I need it for. Enjoy!

A few "Classics" on this topic are: http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=5788 http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=1368 http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=1834

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 17-Jul-2010 03:52:38   

Thanks for sharing! wink

David Elizondo | LLBLGen Support Team
Nightowl33
User
Posts: 8
Joined: 31-Mar-2009
# Posted on: 30-Aug-2010 19:31:36   

Thank you for posting this. I needed to make a couple changes to work for me, so I thought I'd post them back here.

With the routine posted above, the fields were still pointing to each other, so changing something in the copy (after the routine, but before saving) would change the source as well! Not what I needed. This was fixed by copying the Field[i].CurrentValue instead. I also needed to NOT copy a ReadOnly field (a timestamp, in my case). And finally, in my case, I didn't want the entity saved yet - I needed to mess with it before saving it.

Here are my changes, in green. Thanks again! -Scott

public static AddressEntity DuplicateAddress(AddressEntity address)
{
    // Create a new entity object
    AddressEntity newAddress = new AddressEntity();

    // For all of the fields except the PK, copy the field values one by one to the new entity
    for (int i = 0; i < address.Fields.Count; i++)
    {
        if (!address.Fields[i].IsPrimaryKey && !address.Fields[i].IsReadOnly)
        {
            newAddress.Fields[i].CurrentValue = address.Fields[i].CurrentValue; // copy the value
            newAddress.Fields[i].IsChanged = true;   // specify that values have changed in the new object
        }
    }
    newAddress.IsNew = true;                         // specify that the object is new, i.e. generate a new persistent object/db entry
    newAddress.IsDirty = true;                       // specify that things have changed

// I commented this out for my purposes
   //  newAddress.Save();                                // save the new object in the persistent storage

    return newAddress;
}
daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 31-Aug-2010 07:49:05   

Thanks!

David Elizondo | LLBLGen Support Team