Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Added code-first entity doesn't lazy-load properties

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.

like image 587
Appetere Avatar asked Feb 13 '12 14:02

Appetere


People also ask

Does Entity Framework support lazy loading?

Entity Framework supports three ways to load related data - eager loading, lazy loading and explicit loading.

Which of the following entities will allow lazy loading?

Lazy loading by default in Entity Framework We see that for “Timken eng” there are 2 in the location count. As we discussed, lazy loading is enabled by default.

Is lazy loading enabled by default in Entity Framework Core?

The advice is not to use lazy loading unless you are certain that it is the better solution. This is why (unlike in previous versions of EF) lazy loading is not enabled by default in Entity Framework Core.


1 Answers

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;
}
like image 64
Enrico Campidoglio Avatar answered Oct 27 '22 11:10

Enrico Campidoglio