In some instances when IEditablObject.BeginEdit() is called, a StackOverflowException is thrown. Unfortunately this exception cannot be caught, it crashes my application (WinForms app if you care), quite badly too (not even AppDomain.CurrentDomain.UnhandledException catches this).
Up until now I had been using a version of the templates from mid December 2006 and everything had been working fine. Yesterday I updated to the latest templates (v2.1.0.518) and these issues started popping up.
I've traced this for one of the entities where this is occurring, and I believe it is caused by the fact that BeginEdit() calls entityData.Clone() which makes DEEP copies of every referenced object (both the parent composite entities and child collections). A few of my entities are hierarchical, and in most cases the hierarchy is represented through a reference to the parent entity's id (parentId field, basic stuff).
In my case the LocationEntityData class has ParentIdSource and LocationCollection properties both of Location type. What may also contribute to is the amount of data available, I have about 7000 locations in my database, most of them being leaf nodes. Whether you DeepLoad these entities, or as I am doing just get all of them and then iterate through the collection and set the ParentIdSource and LocationCollection props manually, both of those props will be set.
Given the above scenario, trying to make a Deep Copy of this object, is very likely to cause a StackOverflowException. I don't see why a Deep Copy is needed for a BeginEdit(), I've always assumed that for such an operation one only needs to keep a copy of the entity being edited, in the case of child collections, I thought it is enough to just make a shallow copy of the collection itself, keeping the references to the existing objects. Then if any of the child objects need to enter edit mode, BeginEdit() would be called on each respective child entity, and it would do the same in turn, and so on and on....
This Deep Copy business for an entire child collection also flies in the face of the whole idea of EntityTracking in my opinion.
So, here's the table definition for one of my entities, there's nothing special about it:
CREATE TABLE [Locations] (
[id] [int] NOT NULL ,
[parentId] [int] NULL ,
[statusId] [int] NOT NULL DEFAULT (1),
[typeId] [int] NOT NULL ,
[depth] [int] NOT NULL ,
[path] [varchar] (512) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[name] [nvarchar] (256) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[shortName] [nvarchar] (32) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[version] [timestamp] NOT NULL ,
)
CONSTRAINT [FK_Locations_Locations] FOREIGN KEY
(
[parentId]
) REFERENCES [Locations] (
[id]
),
"Small is the number of them that see with their own eyes, and feel with their own hearts" Albert Einstein