Home > .net 3.0, .net 3.5, c#, LINQ, Microsoft, Visual Studio 2008 > Deep Copy Cloning of LINQ Entity Objects – Not Deep Enough

Deep Copy Cloning of LINQ Entity Objects – Not Deep Enough

June 5, 2008

Yesterday, I wrote about a great IL solution to deep copying LINQ objects.  Unfortunately, it’s not quite deep enough.😦

The problem lies in the entity sets related to LINQ objects.  For example, in what I’m working on, the Report object contains Marks (grades) based on a foreign key relationship.  The previously discussed IL cloning method copies the records, but because it doesn’t generate new primary keys for those, it throws:

“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’ve tried zeroing out the PK fields just as I did with the report object iself—no dice.  Removing the Marks (by setting them equal to either null or new EntitySet<Mark>()) and no dice.

The only way I think I can get around it would be to break the FK relationship, clone the report (which would return a new Id), and then copy each of the Marks objects separately with some sort of loop (similar to below):

foreach (var mark in

new MarksController().SelectAll(oldReport.Id))

{

var newMark = new Mark {

              IndicatorId = mark.IndicatorId,

ReportId = newReport.Id,

             ResponseChoiceId = mark.ResponseChoiceId

});

}

That defeats the purpose though… ugh.

Back to the drawing board!

Tags: , , , ,
  1. Sam
    June 16, 2008 at 7:11 am

    Oh, you’ve seen the problem yourself – hope you find a solution soon (I’ll post back if I find one, too).

  2. Sam
    June 16, 2008 at 7:39 am

    I made myself a workaround for this problem, I use the WCF serializer to serialize and deserialize the object to get a deep clone.

    This is slow, but for now it works.

    public static T CloneWithSerializer(T source)
    {
    // Don’t serialize a null object, simply return the default for that object
    if (Object.ReferenceEquals(source, null))
    {
    return default(T);
    }
    DataContractSerializer dcs = new DataContractSerializer(typeof(T));
    using (Stream stream = new MemoryStream())
    {
    dcs.WriteObject(stream, source);
    stream.Seek(0, SeekOrigin.Begin);
    return (T)dcs.ReadObject(stream);
    }
    }

    regards,
    Sam

  3. June 21, 2008 at 8:58 am

    @Sam-

    Hmm, that’s a great idea. I’m not sure if you noticed, but Whizzo left a post on the original article that he was going to find a way to do this via IL. Might keep up on that one too!

  4. June 30, 2008 at 12:56 am

    Howdy folks,

    I’ve adapted the IL code from my site and made a ‘CloneHelper’ class, that’s able to clone through IL, you can specify wether to clone shallow (like originally), deep until normally N-levels, and you can mark fields with attributes to say wether to ignore cloning, do shallow cloning or deepcloning…

    You can view the code at: Object Deep Cloning using IL in C# – version 1.1

    There are at this moment 3 posts regarding this topic, it’s maybe a good thing if you read them all, to fully understand how the system works…

    Another solution based on this methodology, is the checking ofdirtyness of an object (any given object).

    Have fun😉

    Regards,
    F.

  1. No trackbacks yet.
Comments are closed.
%d bloggers like this: