I found out how to blog code snippets here
Simplicy in Software Design and Code
I found out how to blog code snippets here
Update: before trying the code pattern here, see if you can use this instead.
– Chris
I was reading two good blogs about Linq to SQL and ASP.Net applications here and here.
Based on the pattern set up by Rocky Moore (see first link) I came up with this code. Using generics and a little bit of reflection in a base class.
Here is the base class
public class detachableEntity<T> where T : detachableEntity<T>, new()
{
public void OnDataLoaded()
{
original = Clone();
}
public T original { get; set; }
public T Copy()
{
return Copy((T)this);
}
public static T Copy(T Old)
{
T newItem = Clone(Old);
newItem.OnDataLoaded(); // set the original state for the new object to the currect state
return newItem;
}
public T Clone()
{
return Clone((T)this);
}
public static T Clone(T item)
{
if (item == null)
return null;
T newItem = new T();
// copy all subclass properties.
foreach (PropertyInfo prop in item.GetType().GetProperties())
{
PropertyInfo prop2 = item.GetType().GetProperty(prop.Name);
prop2.SetValue(newItem, prop.GetValue(item, null), null);
}
//the two items now share the same orginal state object, fix this by
//cloning the original state object on the item that to create a new original state
//object for the new item
if (item.original != null)
newItem.original = item.original.Clone();
return newItem;
}
}
In the partial classes created by Linq Designer here is how to add the base class
As the pattern is fixed, it is a good candidate for replace all in the partial class file.
partial class Address : detachableEntity<Address>
{
partial void OnLoaded() { base.OnDataLoaded(); }
}
and a usage example
static void Main(string[] args)
{
//Create new Entity
Address home = new Address();
//Create new data context
AdventureWorksDataContext AW = new AdventureWorksDataContext();
//Get Data
home = AW.Addresses.First();
// Disconnect Data Context
AW = null;
//Modify Data
home.City = home.City + “AAA”;
// New Data context
AW = new AdventureWorksDataContext();
//Attach Entity
AW.Addresses.Attach(home, home.original);
//Review Changes
ChangeSet Changes = AW.GetChangeSet();
//Update Data Source
AW.SubmitChanges();
//Dispose Data Context
AW.Dispose();
AW = null;
//Dispose Entity
home = null;
//Create new Data Context
using (AW = new AdventureWorksDataContext())
{
//Create new Entity
Address NewHome = AW.Addresses.FirstOrDefault(addr => addr.City.Contains(“AAA”));
//Modify Data (remove earlier changes)
NewHome.City = NewHome.City.TrimEnd(new char[] { ‘A’ });
//Submit Changes in the same context
AW.SubmitChanges();
}
}
This should be quite useful for detached applications.
-Chris