Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid Lazy Loading when accessing foreign key ID property through navigation property?

I'm in the process of converting a project from NHibernate to Entity Framework 6.

Given this simple model:

public class User
{
    public int ID { get; set; }
    public string FullName { get; set; }
    public virtual Organization Organization { get; set; }
    // [...]
}

public class Organization
{
    public int ID { get; set; }
    public string Name { get; set; }
    public virtual List<User> Users { get; set; }
    // [...]
}

Accessing the primary key (ID) through the Organization navigation property will cause the whole Organization entity to be loaded into the context:

foreach(var user in db.Users)
    Console.WriteLine(user.Organization.ID);

Given that the OrganizationID foreign key is part of the User row, I should be able to access it without causing a Lazy Load of the whole entity (and indeed, NHibernate does this properly).

Short of adding properties for the foreign key IDs into all of my 100+ entities so I can access their values without loading the entities, is there anything to be done to avoid this behaviour?

EDIT: Furthermore, even doing a null check will cause a load of the Organization entity (not in NHibernate):

foreach(var user in db.Users)
    Console.WriteLine(user.Organization != null);

I guess this is due to the fundamental differences in the way the entity proxy is implemented in these two frameworks. So I'll have to adapt all of my code to this new frustrating behaviour... Unless someone already had to go through this and could enlighten me?

like image 760
ECC-Dan Avatar asked Nov 11 '22 17:11

ECC-Dan


1 Answers

Nope, you'll need to add them as property in your class (that is; if you want it strong typed) like this to access it directly.

public class User
{
    public int ID { get; set; }
    public string FullName { get; set; }

    //added ID    
    public int OrganizationID { get; set; }
    public virtual Organization Organization { get; set; }
    // [...]
}

By accessing the int you'll prevent the lazy loading, EF will bind the ID through naming conventions. Having said that: 100+ classes... :|

UPDATE:

As I just realized; you might want to try:

db.Users
        .Include("Organization.ID")
        .Where(/*your stuff*/) //etc.;

I am not certain if it will fully load the nested property. If it doesn't, it might be a small performance gain.

like image 101
Stefan Avatar answered Nov 15 '22 11:11

Stefan