Burtsev-Alexey/net-object-deep-copy

StackOverflow when copying EF entity

Opened this issue · 0 comments

Hi,

The type I was copying looked innocuous enough being a POCO with an IEnumerable property. However these were part of an EF DbContext and at run time that property is lazy loaded so its a DbQuery - that means one massive object graph when recursively including all the private fields. I added some simple debug output to the InternalCopy method so you can see where its going - traversing into other entity types within the same DbContext, etc, etc.

(Note the number after the colon is the 'depth' of the object graph):

MyEntity:1
System.Data.Entity.Infrastructure.DbQuery`1[MyOtherEntityA]:2
System.Data.Entity.Internal.Linq.InternalQuery`1[MyOtherEntityA]:3
System.Data.Entity.Internal.LazyInternalContext:4
System.Data.Entity.Internal.LazyInternalConnection:5
System.Data.Entity.Infrastructure.DbConnectionStringOrigin:6
System.Boolean:6
System.Data.Entity.Infrastructure.Interception.DbInterceptionContext:6
System.Collections.Generic.List`1[System.Data.Entity.DbContext]:7
System.Data.Entity.DbContext[]:8
MyDataContext:9
System.Data.Entity.DbSet`1[MyOtherEntityB]:10
System.Data.Entity.Internal.Linq.InternalSet`1[MyOtherEntityB]:11
System.Data.Entity.Internal.LazyInternalContext:12
System.Data.Entity.Internal.Linq.InternalSet`1[MyOtherEntityB]:11
System.Data.Entity.DbSet`1[MyOtherEntityC]:10
System.Data.Entity.Internal.Linq.InternalSet`1[MyOtherEntityC]:11
System.Data.Entity.Internal.LazyInternalContext:12
System.Data.Entity.Internal.Linq.InternalSet`1[MyOtherEntityC]:11
System.Data.Entity.DbSet`1[MyOtherEntityE]:10
System.Data.Entity.Internal.Linq.InternalSet`1[MyOtherEntityE]:11
System.Data.Entity.Internal.LazyInternalContext:12

I have more output if its useful, I had a guard in there to stop when reaching a depth of 50, otherwise it goes on until the stack overflows.

I realize this maybe a similar outcome to the other stackoverflow issue open on here already, but at least people will note that there are a few different situations this could happen at runtime, without being able to necessarily predict it from the type as written in code.