views:

263

answers:

1

I have a project using Entity Framework 4.0 with POCOs (data is stored in SQL DB, lazyloading is enabled) as follows:

public class ParentObject {
    public int ID {get; set;}
    public virtual List<ChildObject> children {get; set;}
}

public class ChildObject {
    public int ID {get; set;}
    public int ChildRoleID {get; set;}
    public int ParentID {get; set;}
    public virtual ParentObject Parent {get; set;}
    public virtual ChildRoleObject ChildRole {get; set;}
}

public class ChildRoleObject {
    public int ID {get; set;}
    public string Name {get; set;}
    public virtual List<ChildObject> children {get; set;}
}

I want to create a new ChildObject, assign it a role, then add it to an existing ParentObject. Afterwards, I want to send the new ChildObject to the caller.

The code below works fine until it tries to get the object back from the database. The newChildObjectInstance only has the ChildRoleID set and does not contain a reference to the actual ChildRole object. I try and pull the new instance back out of the database in order to populate the ChildRole property. Unfortunately, in this case, instead of creating a new instance of ChildObject and assigning it to retreivedChildObject, EF finds the existing ChildObject in the context and returns the in-memory instance, with a null ChildRole property.

public ChildObject CreateNewChild(int id, int roleID) {
    SomeObjectContext myRepository = new SomeObjectContext();        

    ParentObject parentObjectInstance = myRepository.GetParentObject(id);

    ChildObject newChildObjectInstance = new ChildObject() {
        ParentObject = parentObjectInstance,
        ParentID = parentObjectInstance.ID,
        ChildRoleID = roleID
    };

    parentObjectInstance.children.Add(newChildObjectInstance);
    myRepository.Save();

    ChildObject retreivedChildObject = myRepository.GetChildObject(newChildObjectInstance.ID);

    string assignedRoleName = retreivedChildObject.ChildRole.Name; //Throws exception, ChildRole is null

    return retreivedChildObject;
} 

I have tried setting MergeOptions to Overwrite, calling ObjectContext.Refresh() and ObjectContext.DetectChanges() to no avail... I suspect this is related to the proxy objects that EF injects when working with POCOs.

Has anyone run into this issue before? If so, what was the solution?

+2  A: 

You should not use "new" to create a a new entity, but rather use ObjectContext.CreateObject(). This way the proxy of your object will be instantiated instead of the entity POCO class itself.

I know it's an old question, but I stumbled upon it and just read about that a second ago.

DonAndre