views:

29

answers:

2

Hello all,

I have this extension method for cloning my LINQ To SQL objects:

public static T CloneObjectGraph<T>(this T obj) where T : class 
{
    var serializer = new DataContractSerializer(typeof(T), null, int.MaxValue, false, true, null);
    using (var ms = new System.IO.MemoryStream())
    {
        serializer.WriteObject(ms, obj);
        ms.Position = 0;
        return (T)serializer.ReadObject(ms);
    }
}

But while i carry objects with not all references loaded, while qyuerying with DataLoadOptions, sometimes it throws the object disposed exception, but thing is I don't ask for references that is not loaded (null).

e.g. I have Customer with many references and i just need to carry on memory the Address reference EntityRef<> and i don't Load anything else. But while i clone the object this exception forces me to load all the EntitySet<> references with the Customer object, which might be too much and slow down the application speed.

Any suggestions?

A: 

Suppose you have a Customer, with some Orders.

  • If you use LoadOptions.LoadWith<Customer>(c => c.Orders), your get a Customer and a populated Customer.Orders EntitySet.
  • If you don't, you get a Customer and a lazy loadable Customer.Orders EntitySet. Any attempt to enumerate the Orders property will cause the DataContext to load this customer's orders.

Now that you have the Customer, you dispose the DataContext as should happen (preferable with a using statment).

And some time after that, you serialize. The serialization code enumerates the Orders property. The DataContext that would load those Orders is gone, and you get the error.

Check out EntitySet.IsDeferred and EntitySet.HasLoadedOrAssignedValues.


I'm not 100% sure of the solution, but I'd try something heavy handed like:

if (!c.Orders.HasLoadedOrAssignedValues)
{
  c.Orders = null;
}

as a pre-step to serialization. Any lazy EntitySets must be disconnected from the Customers.

David B
I think the best to this step i have reached with the application is to hang with loading most of the refs i could need and in my next app use PLinqo or start learn EF 4.
+1  A: 

In my experience it is best to keep away from serializing LINQ to SQL objects if possible. Rather use Data Transfer Objects (DTO). They will simply contain data and no hard to serialize references and hidden connections to a DataContext. This way it is easy to serialize them and only serialize the stuff you need to be serialized.

Steven
I'm not quite sure what you mean about DTO, please apply an example if you can. Thank you for your answer.
I added a link to Wikipedia explaining Data Transfer Objects, but there basically isn't anything special about them. They are POCO (plain old CLR objects) and in your case serializable POCOs. Here is an SO answer about DTOs I wrote. I think this also answers your question: http://stackoverflow.com/questions/2785506/linq-to-sql-web-application-best-practices/2786713#2786713
Steven