Search code examples
asp.net-coreentity-framework-corelazy-loadingone-to-manyef-fluent-api

Can't load One To Many navigation property in EF Core


My question may be a littler more specific and I'm just learning EF Core. I have two classes. tblBuilding and tblBuildingHour. Simple classes. Don't mind the naming convention of the tables. It's a legacy database. It works fine if I remove the navigation properties. What am I missing? Is there something I need to do for the Castle proxy configuration? Is it the composite keys? Is it the lazy loading of the navigation property? I'm stumped.

public class tblBuilding {
    public int ID {get;set;}
    public string Name {get;set;}
    public virtual ICollection<tblBuildingHour> BuildingHours {get;set;}
}

public class tblBuildingHour {
    public int BuildingID {get;set;}
    public DateTime BuildingHourDate { get;set; }
    public DateTime StartTime {get;set;}
    public DateTime EndTime {get;set;
    public virtual Building Building {get;set;}
}

There's lazy loading of the entities in my db context.

services.AddDbContext<EMSDataContext>(options => options.UseLazyLoadingProxies()
    .UseSqlServer(Configuration.GetSection(EmsDevDb).Value)
    .UseLoggerFactory(_loggerFactory));

In the dbContext I added the one to many relationship.

modelBuilder.Entity<tblBuilding>()
    .HasMany(b => b.BuildingHours)
    .WithOne(r => r.Building)
    .HasForeignKey(r => r.BuildingID);

The only odd thing in this tblBuildingHour table is that it has a composite keys so I don't know if that's what's messing it up.

modelBuilder.Entity<tblBuildingHour>()
    .HasKey(c => new { c.BuildingID, c.BuildingHourDate });

I wondered if the lazyloading was affecting it so I tried this to no avail.

https://www.learnentityframeworkcore.com/lazy-loading


Solution

  • EF Core creates the relationships provided you create your entity classes correctly. After looking closer at my classes, I removed the fluent api relationship, changed my entity classes to have List instead of ICollection properties, removed .Include from my repo queries, and it worked like a charm. Eager loading wasn't the solution. Surprisingly enough, it wasn't even the composite keys. EF Core managed to create the relationships correctly after I removed mine.

    Addendum: to be clear, removing .Include is not part of the fix, that was only for lazy loading.

    REMOVED

    modelBuilder.Entity<tblBuilding>()
        .HasMany(b => b.BuildingHours)
        .WithOne(r => r.Building)
        .HasForeignKey(r => r.BuildingID);
    

    UPDATED

    [Table("tblBuilding")]
    public class EMSBuilding
    {
        public int ID { get; set; }
        public string Name{ get; set; }
    
        public virtual List<EMSBuildingHour> Hours { get; set; }
    }
    
    [Table("tblBuildingHours")]
    public class EMSBuildingHour
    {
        [Column("BuildingHoursDate")]
        public DateTime BuildingHourDate { get; set; }
        public DateTime OpenTime { get; set; }
        public DateTime CloseTime { get; set; }
    
        public int BuildingID { get; set; }
        public virtual EMSBuilding Building { get; set; }
    }
    
    modelBuilder.Entity<EMSBuildingHour>()
        .HasKey(c => new { c.BuildingID, c.BuildingHourDate });