I have a requirement to clone a Linq to SQL entity. In overview:
Customer origCustomer = db.Customers.SingleOrDefault(c => c.CustomerId == 5);
Customer newCustomer = CloneUtils.Clone(origCustomer);
newCustomer.CustomerId = 0; // Clear key
db.Customers.InsertOnSubmit(newCustomer);
db.SubmitChanges(); // throws an error
where CloneUtils.Clone() is a simple generic method that uses reflection to copy the copy the data from the original entity to the new entity.
The problem I have is that when I try and add the new entity back into the database, I get the following error:
An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported.
I can't seem to find an easy/generic way of detaching the cloned entity from the data context. Or maybe I can adjust my cloning method to 'skip' the context related fields?
Can anyone point me in the right direction?
Thanks.
For completeness, here is the method I ended up with following Marcus's advice:
public static T ShallowClone<T>(T srcObject) where T : class, new()
{
// Get the object type
Type objectType = typeof(T);
// Get the public properties of the object
PropertyInfo[] propInfo = srcObject.GetType()
.GetProperties(
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.Public
);
// Create a new object
T newObject = new T();
// Loop through all the properties and copy the information
// from the source object to the new instance
foreach (PropertyInfo p in propInfo)
{
Type t = p.PropertyType;
if ((t.IsValueType || t == typeof(string)) && (p.CanRead) && (p.CanWrite))
{
p.SetValue(newObject, p.GetValue(srcObject, null), null);
}
}
// Return the cloned object.
return newObject;
}
Only clone public properties
var PropertyBindings = BindingFlags.Public | BindingFlags.Instance;
That are value types or string
var PropType = p.PropertyType.IsValueType || p.PropertyType == typeof(string);
And that are accessible
var IsAccessible = p.CanRead && p.CanWrite;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With