Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Navigation properties not loading properly

My context looks like:

public class ApplicationDbContext: IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("DefaultConnection")
    {
        this.Configuration.LazyLoadingEnabled = true;
    }

    //DbSet properties
}

so, lazy loading is enabled.

I have following class:

public class Home
{
    private ICollection<Slide> _slides;

    [Key]
    [Required]
    public string Name { get; set; }

    [ForeignKey("Header")]
    public int? HeaderID { get; set; }

    //Navigation properties
    public ICollection<Slide> Slides
    {
        get { return _slides ?? (_slides = new List<Slide>()); }
        set { _slides = value; }
    }

    public Content Header { get; set; }
}

Note that both navigation properties Header and Slides are used without virtual keyword. As far as I know when we don't use virtual keyword - properties should load eagerly.

However, when I get my Home entity from database, both my navigation properties are null (but property HeaderID has value).
Even if I switch to this.Configuration.LazyLoadingEnabled = false; - preperties not loaded - they still null.

Here is how I get my data from db (using repository pattern):

public static Home GetHomeComponent(
    this IRepositoryAsync<Home> repository)
{
   var result = repository
       .Query()
       .Select()
       .First();
   return result;
}

I solved my problem with Include properties:

public static Home GetHomeComponent(
    this IRepositoryAsync<Home> repository)
{
   var result = repository
       .Query()
       .Include(x => x.Header)
       .Include(x=>x.Slides)
       .Select()
       .First();
   return result;
}

However it's not convenient for me (since I have too much navigation properties to load).

So, my question is:
I don't use virtual keyword - but why my navigation properties not loading eagerly?
Or I'm doing something wrong? Is there any other way to load my navigation properties without using Include?

like image 405
user3333333 Avatar asked Jun 01 '14 09:06

user3333333


1 Answers

If you don't use the virtual keyword it only means that once you try to access the non-virtual property it wont be loaded from the database but you will get a Null .

It doesn't mean you will have all the properties of the entities populated right away, to populate Slides for E.G in your code, you have to use .Include() - this is eager loading, to load the property by your self before it used .

You can make a generic function that will populate the required properties by the arguments it gets ( using params ) see here for more details :

EntityFramework Eager Load all Navigation Properties

like image 163
jony89 Avatar answered Oct 17 '22 19:10

jony89