Otis wrote:
The thing is that an entity never ends up in the save queue if it's not referenced somewhere by an entity or collection which is examined, like the root entity you're saving.
So if the entity is removed from the queue and you're just saving the entity containing the collection recursively, and the entity removed isn't referenced by any other entity, it shouldn't end up in the queue.
Thanks, Frans, that's what I thought and so I was really puzzled by this.
Do you use a unitofwork perhaps?
No (not yet perhaps I should say). This trace entity is not referenced anywhere else after I remove it.
Following your suggestion, I loaded a file with 10 traces, and flagged one of them, "BIT" for deletion. It appears to be successfully removed from the collection, but it's still in the insertQueue afterwards. Here's the code:
ObjectGraphUtils utils = new ObjectGraphUtils();
ArrayList a1 = new ArrayList();
ArrayList a2 = new ArrayList();
// only trace flagged for removal is "BIT", so this loop only executes once
for (int x = 0; x < toDelete.Count; x++)
{
a1.Clear();
a2.Clear();
utils.DetermineActionQueues(traceSet.Traces, ref a1, ref a2, true);
System.Diagnostics.Trace.WriteLine("PRIOR TO REMOVAL");
System.Diagnostics.Trace.WriteLine("traceSet.Traces.Count: " + traceSet.Traces.Count.ToString());
System.Diagnostics.Trace.WriteLine("a1.Count: " + a1.Count.ToString());
System.Diagnostics.Trace.WriteLine("a2.Count: " + a2.Count.ToString());
foreach (ActionQueueElement element in a1)
{
TraceEntity trace = element.Entity as TraceEntity;
if (trace != null)
System.Diagnostics.Trace.WriteLine(trace.Name);
else
System.Diagnostics.Trace.WriteLine(element.Entity.ToString());
}
// toDelete is an EntityCollection that holds the TraceEntity "BIT"
traceSet.Traces.Remove(toDelete[x]);
a1.Clear();
a2.Clear();
utils.DetermineActionQueues(traceSet.Traces, ref a1, ref a2, true);
System.Diagnostics.Trace.WriteLine("AFTER REMOVAL");
System.Diagnostics.Trace.WriteLine("traceSet.Traces.Count: " + traceSet.Traces.Count.ToString());
System.Diagnostics.Trace.WriteLine("a1.Count: " + a1.Count.ToString());
System.Diagnostics.Trace.WriteLine("a2.Count: " + a2.Count.ToString());
foreach (ActionQueueElement element in a1)
{
TraceEntity trace = element.Entity as TraceEntity;
if (trace != null)
System.Diagnostics.Trace.WriteLine(trace.Name);
else
System.Diagnostics.Trace.WriteLine(element.Entity.ToString());
}
}
and the output (I've added a couple of blank lines and the comment):
PRIOR TO REMOVAL
traceSet.Traces.Count: 10
a1.Count: 13
a2.Count: 0
Chevron.RMA.DAL.EntityClasses.TraceSetEntity
ZDEN
CNCF
CVOL
BVOL
Chevron.RMA.DAL.EntityClasses.LASFileSectionEntity
BIT
CAL
WTBH
Chevron.RMA.DAL.EntityClasses.LASFileSectionEntity
DEPT
GR
DT
AFTER REMOVAL
traceSet.Traces.Count: 9
a1.Count: 13
a2.Count: 0
Chevron.RMA.DAL.EntityClasses.TraceSetEntity
ZDEN
CNCF
CVOL
BVOL
Chevron.RMA.DAL.EntityClasses.LASFileSectionEntity
BIT // still there!
CAL
WTBH
Chevron.RMA.DAL.EntityClasses.LASFileSectionEntity
DEPT
GR
DT
It would appear that it is a) getting removed from parent entity's collection, and b) getting parent FK value nulled out (see original post). But it is also still in that queue after the removal, and I suppose that is why the attempted insert is happening?
I could post the code that originally creates the TraceEntity and adds it to the parent, but I just double-checked that, it is all very straightforward; again, I don't see where any other entity is referenced by this one, or vice versa. Remember that the insert statement doesn't contain fields from any other table (it couldn't; TraceSetID is the only FK in the Traces table).
BTW I'm running 1.0.2005.1 March 31st.