2

I've been researching this quite a lot and I still have not found a solution to clone an entity and be able to save it including all levels of child relationships.

Does anyone know a way on how to do it?

BTW I got this working using AsNoTracking() and then using Include("Child...") but I have 5 levels of relationships in my database and about 100 tables that need to be included so I'm after an automatic way of doing this

user441365
  • 3,934
  • 11
  • 43
  • 62

1 Answers1

0

I tried 3 different ways, with serialization (not usable in most cases because of Lazy load), implementing ICloneable on a base entity with reflection and using custom attributes to control the Clone behavior (I think that you're looking for this) and implementing ICloneable on every single Entity.

Actually I implement ICloneable on every single entity. Usually I do this:
1. MemberwiseClone()
2. call ICloneable.Clone of related entities to fill properties (only on some properties
3. on some other related entities I make a shallow copy (depends on the needs)

I know that is bad but in my experience if I use other methods when the project starts Clone works fine but after 6 months calling Clone on some entities clones half the database.

In you case, with lazy load activated, you could use reflection.
1. Ignore simple property
2. call Clone for every complex property
3. do a foreach on every ICollection property calling Clone and adding the result to a corresponding list

The problem in this approach is that you will clone the entire database every time. You can decide to stop on some entities overriding Clone or using custom attributes on properties but you need something to avoid cloning the entire DB.

If you don't activate lazy load there are this methods you can call before clone.

context.Entry(myEntry).Reference("myRefProp").Load(); 
context.Entry(myEntry).Collection("myColl").Load(); 

but they don't solve your problem.

EDIT
I still have the code to apply this method (with attributes), I don't use it since ages but if you need I can post it somewhere. Actually I implement always the ICloneable on every entity because using attributes to stop serialization or stopping it in Clone implementation is better stopping it in Clone implementation.

bubi
  • 6,414
  • 3
  • 28
  • 45
  • Is this an answer or an augmented question? If the latter: then you should add this to your question. The problem is that it's not clear what you're after. On the one hand you seem to have to clone 100 tables, on the other hand you don't want to "clone the entire database every time". What's the use case? – Gert Arnold Jun 17 '15 at 20:18
  • Probably the answer is between the lines. When you deep clone an object tree you have to choose how to stop independently from the technology. Then you can choose how to apply it (actually I implement ICloneable Clone on every entity after using different approaches) but this is the second step. – bubi Jun 18 '15 at 08:41