Search code examples
entity-frameworklazy-evaluationeager-loadingempty-list

Entityframeworkcore Include method doesnt working. Eager Loading Lazy Loading doesn't working correctly


Relationship tables are not added to stations(Lists) when I use the Include () method. eager loading and lazy loading both do not work.the associated station list is always zero.I'm using aspnet core mvc 5.0. any library missing? It pulls data from the database but does not fetch any associated data.

[HttpGet]
    public IActionResult Index(int? SayfaNo)
    {
        int _sayfaNo = SayfaNo ?? 1;

        // Proplem is here. Networks.Stations.Count=0  always 
        var networks = _context.Networks.Include(x=>x.Stations).ToList();
            //.ToPagedList<Network>(_sayfaNo, 9);
        if (networks == null)
        {
            return View(networks);
        }
        var request = Request;
        if (request.Headers!=null)
        {
            if (request.Headers["X-Requested-With"] == "XMLHttpRequest")
            {
                return PartialView("~/Views/Home/_BicycleListPartialView.cshtml", networks);
            }
        }
        return View(networks);

    }

public class Network:BaseEntity
{
    public Network()
    {
        Stations = new HashSet<Station>();
    }
    public string NId { get; set; }
    public string Name { get; set; }
    [ForeignKey("Location")]
    public int LocationId { get; set; }
    public virtual  Location Location { get; set; }
    public virtual ICollection<Station> Stations { get; set; }
}
public class Location:BaseEntity
{
    public string Country { get; set; }
    public string City { get; set; }
    public virtual Network Network { get; set; }

}
public class Station:BaseEntity
{
    public string SId { get; set; }
    public string Name { get; set; }
    public int? FreeBikes { get; set; }
    public int? EmptySlots { get; set; }
    [ForeignKey("Network")]
    public int NetworkId { get; set; }

    public virtual Network Network { get; set; }
}
public class BaseEntity
{
    [Key]
    public int Id { get; set; }
}

Solution

  • I see a couple issues:

    [ForeignKey] attributes can be put on either the navigation property or the FK field, however the attribute must point to the other property. I.e. if you put it on the FK field, it should point to the navigation property:

    [ForeignKey("Network")]
    public int NetworkId { get; set; }
    public virtual Network Network { get; set; }
    

    .. or this:

    public int NetworkId { get; set; }
    [ForeignKey("NetworkId")]
    public virtual Network Network { get; set; }
    

    There also looks to be a conflicting one to one relationship declared between Location and Network where Network is expected to have a single Location and Location has a single Network. By default one-to-one relationships expect to join on the PKs of the two tables. If this is a many-to-one relationship (Network has one location, location can be part of many networks, but can have a "default" network) then Location would need a FK for the Network. (I.e. DefaultNetworkId) and the relationship between network and location will need to be explicitly configured. The same if instead the many-to-one relationship goes from Location to Network. If instead it is a one-to-one relationship then I believe EF Core can configure 1-to-1 /w paired FKs, otherwise it would expect their ID's to match. Either way it would likely require some explicit configuration for the relationship.

    The next thing is that I would avoid initializing reference navigation properties in a constructor. Initializing child objects or collections is fine, but avoid initializing references:

    public Network()
    {
        // Location = new Location(); <- don't initialize as a *new* one is not a valid state.
        Stations = new HashSet<Station>();
    }