I just updated an entire WCF app from EF4 / AutoMapper 1.1 to EF6 / AutoMapper 6.0.0.2 and the behavior is not completely the same.
This doesn\'t wor
You don't mention it explicitly, but you didn't only move from EF 4 to 6, but also from ObjectContext
to DbContext
. That's a tremendous difference in behavior of the entity classes.
In the ObjectContext
API the generated entity classes were stuffed with code that cooperated closely with the context they were involved in. A reference property like child.Parent
would look like:
public Parent Parent
{
get
{
return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Parent>("model.FK_Child_Parent", "Parent").Value;
}
set
{
((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Parent>("model.FK_Child_Parent", "Parent").Value = value;
}
}
So setting this property is setting the Value
property of an EntityReference<Parent>
. EF4.1's code isn't public, so we can only guess what happens inside. One thing is clear: it changes child
s state into Added
-- if child
wasn't yet attached to the context.
Fortunately EF abandoned this rigid vendor lock-in when it released the DbContext
API (in EF 4.1 no less). Now this generated property isn't anything but an auto-property:
public Parent Parent { get; set; }
This made it much easier to unify the database-first and code-first modes of working with EF. In fact, both code-first and database-first entity classes were POCOs now.
The price (if you like) is that EF can't keep as close a track of everything that happens as it could before. Before, all entity classes inherited from EntityObject
, and EF could keep track of all of their interactions. The statement...
child.Parent = parentObject;
would draw the yet unknown child
into the context through the attached parentObject
.
Now, when someone sets child.Parent
, no one but child
knows what happened, not even Parent
. Which means: there is no way whatsoever for EF to become aware of this change when its change tracker executes DetectChanges
(as it does very frequently).
That's why using DbContext
you have to add a new child to the context yourself, either by explicitly setting its state, or adding it to context.Children
. Or by adding it to parent.Children
, which is a change the change tracker can detect, if parent
is attached.