2

I am a new .NET developer. I have 2 entity classes like this

public class Student
{
    public int userId { get; set; }
    public string username { get; set; }
    public string firstname { get; set; }
    public string lastname { get; set; }
    public string email { get; set; }
    public Course course { get; set; }
}

public class Course
{
    [Key]
    public int courseId { get; set; }
    public String courseName { get; set; }
}

I am using the DB Context Object like this

using (MyDbContext db = new MyDbContext())

When I access the Student object using

Student stdent = db.students.Find(1);

the member variables of native type(int,string) in the student object contains values but course variable of type(Course) is returned null.

Whereas, when I use

var result = from student in db.students where student.userId == 1 select student;

the result contains values for all member variables(entire course object is present here)

Is this the expected behavior or am I missing or overlooking something?

I even added this constructor in my DB Context to disable Lazy Loading but didn't help

    public MyDbContext() : base()
    {
        this.Configuration.LazyLoadingEnabled = false;
    }
user1429007
  • 308
  • 1
  • 3
  • 10

2 Answers2

0

With lazy load only the initial object is loaded. In order to get the second option to retrieve the Course information you will need to specify in load options.

DataLoadOptions dataLoadOptions = new DataLoadOptions();
dataLoadOptions.LoadWith<Customer>(c => c.Course);
db.LoadOptions = dataLoadOptions;

Student stdent = db.students.Find( c=>c.userid == 1).FirstOrDefault();
Victor
  • 676
  • 1
  • 5
  • 17
0

What happens here is that in the first case (Find) you fetch an object from the database. Course is not lazy loading, so the Course reference is null.

In the second case you're only defining a query but not executing it. I assume that you loop through the results afterwards and a the same time check whether Course is present. That causes Course to get loaded because you access the Course navigation property at execution time, it has become part of the query.

If you do

var s = (from student in db.students where student.userId == 1 select student)
        .Single();

you will notice that Course is empty, because the student is fetched without a reference to Course at the moment the query is ececuted (the Single statement).

Gert Arnold
  • 105,341
  • 31
  • 202
  • 291
  • In the first case, Even if I set lazy loading to false(as I have said in the question) and try to access course, it still gives me null. Any idea why is that. – user1429007 Mar 01 '13 at 15:25
  • 1
    Yes, it will never lazy load, because the property is not virtual. Irrespective of lazy loading settings of the context. It's only loaded by _eager loading_. Which is, either through `Include` or by addressing it in a linq query like `Students.Select(s => s.Course)`, or by the `Load` method. – Gert Arnold Mar 01 '13 at 15:31
  • 1
    I think part of your confusion is that the opposite of "lazy = false" (at the context level) does not mean "eager = true". With "lazy=true" lazy loading occurs if possible (i.e. with `virtual` properties). With "lazy=false" _no_ loading will occur unless explicitly demanded by the three options I mentioned above. – Gert Arnold Mar 01 '13 at 15:43
  • Thanks. That clarifies things a lot – user1429007 Mar 01 '13 at 16:44