2

I'm using EF 4.1 Code first. I have a model of user and a model of setting.
Each time the repository returns a user the Setting is also loaded. I've marked the Setting as virtual all my access modifiers are public LazyLoadingEnabled and ProxyCreationEnabled are enabled by default.
What am I missing?

public class User : BaseEntity
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string Password { get; set; }
    public virtual ICollection<Setting> Settings { get; set; } 
}

public class Setting
{
    public int UserID { get; set; }
    public int SettingID { get; set; }
    public string Value { get; set; }
}

The User might have several setting, so there is a one to many relationship with a foreign key in setting.
The user configuration is

public class UserConfiguration : EntityTypeConfiguration<User>
{
    public UserConfiguration()
    {   
        HasKey(u => u.ID);
        HasMany(u => u.Settings).WithOptional().HasForeignKey(u => u.UserID);
    }
}

and the Setting configuration is:

 public class SettingsConfiguration : EntityTypeConfiguration<Setting>
{
    public SettingsConfiguration()
    {
        ToTable("UserSettings");
        HasKey(s => new { s.UserID, s.SettingID });
    }
}
Sagi
  • 8,972
  • 3
  • 33
  • 41
  • *Each time the repository returns a user the Setting is also loaded* What do you mean by that? How does your repository user retrieval look like? – Ladislav Mrnka Jun 03 '11 at 08:13
  • how did u check whether they lazy loaded or not. eg : if you inspected it in debug mode, it will show the values of the collection(by lazy loading). check the sql generated by EF when you access the User/Users – Eranga Jun 03 '11 at 08:54
  • My repository retrieval is straightforward using single on the DbSet, and yes i have inspected it in debug mode. Any suggestions how to inspect it without sql profiler or any other third party tool like entity framework profiler? – Sagi Jun 03 '11 at 09:27
  • 1
    how did u conclude that they are not lazy loaded? – Eranga Jun 03 '11 at 14:01
  • I thought that if they are marked virtual they shouldn't be populated incase I don't use include. – Sagi Jun 03 '11 at 19:07
  • By marking them virtual they are not loaded, but the second you try to look at the values of these properties in visual studio debugger, or access them in code, EF will load them from the database. Unless lazy-loading is set to false. – Alexandre Brisebois Jun 03 '11 at 21:08

1 Answers1

3

Lazy loading means the opposite of what you think it means.

  • With lazy loading (virtual property and defaults)
    • Settings is not retrieved immediately when querying User
    • Settings is retrieved when it's accessed for the first time. The DbContext must be open at that time for this to happen; otherwise you'll get an exception
  • Without lazy loading (non-virtual property and/or explicitly disabled)
    • Settings is not retrieved immediately when querying User
    • Settings will never be retrieved automatically; it will return null (which, in my opinion, is a terrible design decision: null is a wrong value and you shouldn't be able to get it)

In both cases, you can load Settings eagerly by using .Include(x => x.Settings), or when needed, by calling context.Entry(user).Collection(x => x.Settings).Load()

Diego Mijelshon
  • 52,548
  • 16
  • 116
  • 154