cas4
cas4

Reputation: 363

EF6: Forcing Navigation Property to load after setting FK Property

I'm finally upgrading from EF 4.5 to EF 6.1 but I'm encountering some different behaviors I'm not able to overcome. I'm working with a Database-First design.

I have a Person table with a CompanyID FK property and a Company navigation property:

public partial class Person
{
    ... other properties ...
    public int CompanyID { get; set; }
    public virtual Company Company { get; set; }
}

When I load a person object using the syntax

dbcontext.Persons.FirstOrDefault(p => p.Id == id)

the returned person object has the CompanyID set and the Company property is lazy loaded as expected (I use the Database.Log to output generated SQL and verified Company is lazy loaded).

My problem is when the CompanyID is initially null. If I set it's value, I cannot get the Company property to lazy load based on the new CompanyID value. This worked in EF4.5, so I was hoping there was a similar way in EF6 to get the same behavior.

Any ideas? Thanks in Advance.

* Edited * I forgot to include the "virtual" keyword on the Company property in the code example above.

Upvotes: 1

Views: 341

Answers (1)

Ivan Stoev
Ivan Stoev

Reputation: 205729

Unfortunately you are right, there seem to be some weird lazy loading behaviors in EF6.

For the rest of the readers, here are the two scenarios that show two (both incorrect) behaviors. Assume the database contains 2 Company records with Id = 1 and 2, and Customer record with CompanyId = 1.

(A)

var e = db.Employees.FirstOrDefault(x => x.Id == 1);
e.CompanyId = 2;
var c = e.Company;

Result: variable c contains null

(B)

var e = db.Employees.FirstOrDefault(x => x.Id == 1);
var c1 = e.Company;
e.CompanyId = 2;
var c2 = e.Company;

Result: variable c2 is the same as c1 and references the Company with Id=1

Unfortunately all I can suggest you is a workaround and not a general solution. The workaround is to include calls like this after changing the FK property:

e.CompanyId = 2;
db.Entry(e).Reference(x => x.Company).IsLoaded = false; // The "fix"
var c = e.Company; // Works

Upvotes: 2

Related Questions