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.