davioooh
davioooh

Reputation: 24706

Related entity not loaded

I'm starting a new entity framework project and I'm defining relations among entities.

I defined this simple entities:

[Table("db_owner.Students")]
public partial class User 
{
    [Key]
    public int Id { get; set; }

    [Required]
    [StringLength(50)]
    public string Name { get; set; }

    public int? SchoolClassId { get; set; }

    [ForeignKey("SchoolClassId")]
    public SchoolClass SchoolClass { get; set; }
}

[Table("db_owner.SchoolClasses")]
public partial class SchoolClass 
{
    [Key]
    public int Id { get; set; }

    [Required]
    [StringLength(50)]
    public string Name { get; set; }
}

But when I retrieve a Student from the DB the SchoolClass property is null.

I also tried to specify relationship in OnModelCreating method of DBContext definition, but nothing changes:

modelBuilder.Entity<Student>()
   .HasOptional(s => s.SchoolClass).WithMany().HasForeignKey(s => s.SchoolClassId);

What is wrong in my code?

Upvotes: 1

Views: 46

Answers (3)

astef
astef

Reputation: 9508

Mark your relation property with virtual keyword for EF's proxy to be able to overload it:

[ForeignKey("SchoolClassId")]
public virtual SchoolClass SchoolClass { get; set; }

Also, be sure that context's DbContext.Configuration.ProxyCreationEnabled property value is set to true (by default it is).

These two conditions enabling lazy loading of your relations.

If you want explicitly load them, use include mechanism.

Upvotes: 2

Craig
Craig

Reputation: 119

Lazy-loading is invoked for navigation properties that are marked as virtual. Otherwise you must explicitly tell Entity Framework to load the related data.

Upvotes: 0

Antoine Aubry
Antoine Aubry

Reputation: 12469

Entity framework won't load all related entities automatically, because that would cause it to potentially load a significant portion of the database.

You can use the Include method to specify the relationships that you want to load:

myDbContext.Users
    .Include(u => u.SchoolClass)
    .FirstOrDefault(u => u.Id == myId);

You can also make the SchoolClass property virtual. Assuming that you have lazy loading enabled, this will allow Entity Framework to generate a derived class that will load the related entity when the property is accessed for the first time. Notice, however, that this will cause another database query, while Include won't.

Upvotes: 1

Related Questions