EF6 AutoMapper6 Parent/Child different behavior

前端 未结 1 493
借酒劲吻你
借酒劲吻你 2021-01-23 13:02

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

相关标签:
1条回答
  • 2021-01-23 13:12

    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 childs 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.

    0 讨论(0)
提交回复
热议问题