0

How I can clone a Self-Tracking Entity Graph in EF 4.0?

Thanks

Ladislav Mrnka
  • 349,807
  • 56
  • 643
  • 654

2 Answers2

1

Self tracking entities are serializable so the simplest way to get deep clone of the entity (deep clone = clone of the graph) is to use DataContractSerializer and serialize and immediately deserialize it. Deserialized entity will be your clone of the graph.

Ladislav Mrnka
  • 349,807
  • 56
  • 643
  • 654
  • I might be wrong, but I believe this will start pulling data from the DB, rather than restricting data to that which you explicitly queried, since it will follow all the navigation properties in an unrestricted fashion. You'll get the whole object graph, whether you like it or not. – Merlyn Morgan-Graham Dec 06 '11 at 22:07
  • 1
    @Merlyn: This will not happen for real STEs because they don't support lazy loding to avoid exactly this issue. With POCOs you must turn off proxy creation to make this work. EntityObject based entities also support this out of the box because they are generated as serializable. – Ladislav Mrnka Dec 06 '11 at 22:12
  • What do you mean by "real"? As in, "real men don't use that feature", or that it is provably a worthless/harmful feature? Or something else? Can you provide a reference for that? Not challenging you, I'm here to learn :) – Merlyn Morgan-Graham Dec 06 '11 at 22:15
  • So far I've solved this problem by not exposing entities outside the layer that deals with DB operations, and bubbling up classes that expose less data to higher level layers (e.g. passing "view models" to MVC views). It seems to me that serializing an entity is "doing it wrong". Do you have a different opinion? – Merlyn Morgan-Graham Dec 06 '11 at 22:22
  • 1
    @Merlyn: Real STE is entity created by Self Tracking Entities T4 Generator. [Here](http://stackoverflow.com/questions/6571954/self-tracking-entities-and-lazy-loading) is my other answer with links to references. – Ladislav Mrnka Dec 06 '11 at 22:23
  • 1
    @Merlyn: STEs are supposed to work with WCF not with simple MVC layers but I'm really not fan of STEs - [1](http://stackoverflow.com/questions/3814706/self-tracking-entities-vs-poco-entities/3815968#3815968), [2](http://stackoverflow.com/questions/6642390/is-it-recommended-to-use-self-tracking-entities-with-wcf-services) – Ladislav Mrnka Dec 06 '11 at 22:29
  • I want to persist the clone not just make in memory copy – user440916 Dec 07 '11 at 07:12
  • some code that clones entities using DataContract serialization/deserialization : http://naspinski.net/post/Cloning-an-Entity-in-Linq-to-Entities.aspx – surfen Dec 22 '11 at 01:17
0

When you say "clone", do you mean to create a new entity that will be persisted, or to just create another "transient" entity that is an in-memory copy of the same entity?

If you want to make an in-memory copy, you can always create a new instance of the entity class, and copy over the fields. Changes to it won't be tracked, since you haven't told the context about it.

var newInstance = new SomeEntity() { SomeProperty = oldInstance.SomeProperty };

If you want to create a new entity that will be persisted, then simply do the normal operations you'd do to insert a new record. E.g.:

context.SomeEntities.Add(newInstance);

You can't logically make a full copy that tracks changes, but refers to the same instance. Which version of the object would you take?

Merlyn Morgan-Graham
  • 54,918
  • 14
  • 119
  • 174