Problem using LINQ to SQL with Workflow Foundation
Hi!
I'm trying to migrate an application layer by layer from .NET 3.0 to .NET 3.5. For the data layer, I'm using LINQ to SQL and in the business layer, I have a Workflow using WorkflowServices(ReceiveActivity/CodeActivity). I have a data access method that performs an update like the following:
Code Snippetpublic
Expense Update(Expense expense){
using (ExpenseDBDataContext dc = new ExpenseDBDataContext())
{
dc.Expenses.Attach(expense, true);
try
{
dc.SubmitChanges();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw ex;
}
}
return expense;
}
The Workflow keeps a copy of the Expense entity. The update method is supposed to execute and return the latest Timestamp from the database table.
The following error occurs when the Workflow invokes the update method:
Type 'System.Data.Linq.ChangeTracker+StandardChangeTracker' in Assembly 'System.Data.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.
I have already set the Serialization mode of the entity to Unidirectional. I have also disabled all relationships in the Entity (no EntitySet).
The error occurs after the execution of the Update method. It appears that once an entity is re-attached to a datacontext for update, it can no longer be used in workflow foundation. Take note that at this point, there are no custom serialization code in the application. Workflow Foundation appears to be performing its own serialization that doesn't work well with LINQ to SQL.
I would like to know how can we make LINQ to SQL work with Workflow Foundation in this scenario?
Thank You
All Replies
Is your Expense entity marked with [DataContract] attribute?
Petar.
Hi Petar,
Yes, the entities are marked with [Data Contract] attribute.
Have you tried setting DB.ObjectTrackingEnabled to false in your update method?
[)amien
Hi Damien,
If I set ObjectTracking to false, the Update would fail.
I think it is required for this line
dc.Expenses.Attach(expense, true);
to work.
I have created a workaround
Code Snippetusing
(ExpenseDBDataContext dc = new ExpenseDBDataContext()){
Expense temp = base.Clone<Expense>(expense);
// Insert the values. Datacontext will be attached here.
dc.Expenses.Attach(temp, true);
try
{
dc.SubmitChanges();
// Retrieve the updated copy of the entity which contains an updated
// Timestamp but we need it without the datacontext.
expense = base.Clone<Expense>(temp);
}
catch (ChangeConflictException ccex)
{
throw new ApplicationException("The expense record that you are trying to update maybe out-dated. Please refresh and try again.", ccex);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw ex;
}
}
return
expense;where Clone() is
Code Snippetprotected
T Clone<T>(T entity){
DataContractSerializer serializer = new DataContractSerializer(typeof(T));
MemoryStream memory = new MemoryStream();
serializer.WriteObject(memory, entity);
memory.Position = 0;
T cloneCopy = (T)serializer.ReadObject(memory);
memory.Close();
return cloneCopy;
}
The entire sample project is hosted in Codeplex - Layered Architecture Sample project.


