1

I have recently started using generic repository pattern in my new application, I have been following this guide by Chris Pratt Truly Generic Repository. I am eagerly loading my navigation properties in my GetQueryable Method like this

if (includeProperties != null)
        {
            foreach (var includeProperty in includeProperties.Split
                (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
            {
                query = query.Include(includeProperty);
            }
        }
else
        {
            foreach (var property in context.Model.FindEntityType(typeof(TEntity)).GetNavigations())
                query = query.Include(property.Name);
        }

Now the first level of navigation properties are loading fine but if I have a navigation property inside a navigation property i.e. at second level it is not being loaded hence returns null,

public partial class Project : Entity<int>
{
    public Project()
    {
        this.UserProjects = new HashSet<UserProject>();
    }
    [Required]
    public string Title { get; set; }
    public virtual ICollection<UserProject> UserProjects { get; set; }  
}

public class UserProject : Entity<int>
{
    public int UserId { get; set; }
    public virtual User User { get; set; }
    public int ProjectId { get; set; }
    public virtual Project Project { get; set; }
}

public class User : IdentityUser<int>
{
    public User()
    {
        this.UserProjects = new HashSet<UserProject>();
    }  
    public Photo Photo { get; set; }
    public virtual ICollection<UserProject> UserProjects { get; set; }             
}

Here when I query Projects the UserProjects are populated correctly and inside UpserProjects Project is also getting populated but User is null although UserProject has userId.

ABM
  • 19
  • 4
  • Using `...GetNavigations()` to get your includes seems a nasty way to do this as it means all queries will always include every single first level child navigation property. The article you link allows you to pass in only the items you need from the next level up, is there a reason you're note using that? – DavidG Dec 23 '18 at 13:34
  • 1
    From the article "...Probably like many new MVC developers, this was one of my first stops when learning the ropes..." that's exactly what's wrong. You are a new MVC developer, you have NO use for the dreaded Repository pattern. Leave it die, it basically has no place in .NET Framework with Entity Framework Core – Camilo Terevinto Dec 23 '18 at 13:37
  • @CamiloTerevinto I'd disagree that the repository pattern has no place. Unit of Work pattern, yes, that can burn, but repositories are extremely useful. – DavidG Dec 23 '18 at 13:41
  • @DavidG I said "basically" :) let's face it, no new/junior developer will ever have the responsibility of making such a complex architecture so that EF can be easily swapped with, say, Dapper. That article has hundreds of lines of code that just call DbContext's methods, for what, exactly? Will new people that join the team know what's that for? I doubt so. And even so, you really have to have a lot of saying so that anyone will pay for that swapping – Camilo Terevinto Dec 23 '18 at 13:44
  • @CamiloTerevinto *no new/junior developer will ever...* Funnily enough, not too long ago I gave that task to a junior dev! – DavidG Dec 23 '18 at 13:49
  • @DavidG And then you showed him how to use EF's included Repository and UoW and he understood what others have to deal with by misusing EF? I certainly hope the implementation you asked them to do was far better and easier than the one linked here – Camilo Terevinto Dec 23 '18 at 13:55
  • @DavidG Actually I am loading all navigation properties if includedProperties parameter is not passed to the method. And should I query again in case if I need the 2nd level of properties? – ABM Dec 23 '18 at 14:31
  • See https://stackoverflow.com/questions/49593482/entity-framework-core-2-0-1-eager-loading-on-all-nested-related-entities – Ivan Stoev Dec 23 '18 at 14:48
  • @IvanStoev thanks for the link, I added the extention and used it in my repository getting all other refrences but still getting user as null – ABM Dec 23 '18 at 15:57
  • Just to see if there is some problem with the relationship, what happens if you call the repository method and pass "UserProjects.User" as `includeProperties` – Ivan Stoev Dec 23 '18 at 17:05
  • @IvanStoev, User is getting populated correctly if I pass UserProjects.User in includeProperties – ABM Dec 24 '18 at 04:25
  • How about "UserProjects.User.Photo" then? Because that's what custom extension method `GetIncludePaths` is returning for your `Project` model. And it works in my test (loads everything - `Project.UserProjects`, `UserProject.Project`, `UserProject.User` and `User.Photo`). Tested with EF Core 2.2, SqlServer (LocalDB). – Ivan Stoev Dec 24 '18 at 10:01

0 Answers0