Taking a snapshot (clone) of a project using Linq 2 Sql
I have a Project object with multiple child tables like ProjectAwards ProjectTeamMember
I would like to copy data from Project (and child tables) to a new Project record and update the Project status.
eg,
var projectEntity = getProjectEntity(projectId); draftProjectEntity = projectEntity draftProjectEntity.Status = NewStatus context.SubmitChanges();
I found this link from Mark Gravell
Its part of the path is there, but it updates the child entries in the new project of the project where I need to copy it.
a source to share
Unfortunately what you are doing here is setting the variable draftProjectEntity
to an object reference projectEntity
. That is, they now point to the same object. What you need to do is a deep clone projectEntity
.
There are ways to do this with Reflection - if you're going to be doing this a lot - then I highly recommend you look into this method.
However, if your only one to go one level deep, or just for a small graph of objects, then it might be worth just doing it manually and implementing your own IDeepCloneable on your entities ...
public interface IDeepCloneable<T>
{
T DeepClone();
}
public class Person : IDeepCloneable<Person>
{
public string Name { get; set; }
public IList<Address> Addresses { get; set; }
public Person DeepClone()
{
var clone = new Person() { Name = Name.Clone().ToString() };
//have to make a clone of each child
var addresses = new List<Address>();
foreach (var address in this.Addresses)
addresses.Add(address.DeepClone());
clone.Addresses = addresses;
return clone;
}
}
public class Address : IDeepCloneable<Address>
{
public int StreetNumber { get; set; }
public string Street { get; set; }
public string Suburb { get; set; }
public Address DeepClone()
{
var clone = new Address()
{
Street = this.Street.Clone().ToString(),
StreetNumber = this.StreetNumber, //value type - no reference held
Suburb = this.Suburb.Clone().ToString()
};
return clone;
}
}
//usage:
var source = personRepository.FetchByName("JoeBlogs1999");
var target = source.DeepClone();
//at this point you could set any statuses, or non cloning related changes to the copy etc..
targetRepository.Add(target);
targetRepository.Update;
For information on why I am not using the ICloneable interface to do this ... check out this thread: Should I provide a deep clone when implementing ICloneable?
a source to share