14
votes

I have a problem where a property of a newly added entity is not lazy-loaded, if required immediately after adding the entity.

For example:

I have a User entity with a virtual JobRole property:

public class User
{
    public int Id { get; set; }

    public virtual JobRole JobRole { get; set; }
    public int JobRoleId { get; set; }

    public string Name { get; set; }
}

I then add a new User:

public User Add(User user)
{
    var addedUser = _myContext.Users.Add(user);
    myContext.SaveChanges();
    return addedUser;
}

The returned reference to the new User is then passed to a Razor view, where it tries to display the JobRole (eg JobRole.Name). At the point that the User is passed to the View, it has:

  • JobRoleId set correctly to an integer value.
  • JobRole = null

I would then expect JobRole to be lazy-loaded, when used by the View, but it isn't and results in a null-reference exception.

Is this expected behaviour, or is there a way to get newly added entities to lazy-load their properties?

Thanks in advance for any ideas.

Environment: Using Entity Framework 4.2 code-first. Lazy-loading enabled.

2
I had this problem and the answer is correct. However, my code uses database-first. So I suggest you editing the title so future search can land here more easily.Luke Vo

2 Answers

20
votes

That's because the DbSet.Add method returns the same object that has been passed to it as argument, which in your case isn't a proxy instance hence lazy loading is not available.

You should create the User object that's being passed to DbSet.Add using the DbSet.Create method, which will return a proxy instance, and then assign its properties before persisting it through the DbContext.

Here's an example:

public User Add(User user)
{
    var newUser = _myContext.Users.Create();

    // Copy the property values from 'user' to 'newUser' e.g.
    // newUser.Name = user.Name

    _myContext.Users.Add(newUser);
    myContext.SaveChanges();

    return newUser;
}
1
votes

You can try two things, the first one is enforce the eager-loading:

context.ContextOptions.LazyLoadingEnabled = false;

If this doesn't work, you can load the property using this: http://msdn.microsoft.com/en-us/library/dd382880.aspx