Question

From my Web API service using a generic-repository/uow pattern with EF6, I need to return nested navigation properties. Model A has a Model B and Model B has a Model C and so on. Something like this:

public class A
    {
        public int SomeID { get; set; }
        public ICollection<B> Bs { get; set; }
    }    
public class B
    {
        public int SomeID { get; set; }
        public ICollection<C> Cs { get; set; }
    }

I can get the Bs in A, but the Cs in B are null. This is how I'm doing it:

// GENERIC REPOSITORY
public IQueryable<TEntity> Get(params Expression<Func<TEntity, object>>[] includes)
        {
            IQueryable<TEntity> query = _dbSet;
            if (includes != null)
            {
                foreach (var include in includes)
                    query = query.Include(include);
            }
            return query;
        }
//  FROM THE "A" CONTROLLER
public HttpResponseMessage Get()
        {
            HttpResponseMessage response;
            var results = _unitOfWork.A_Repository.Get(s => s.Bs);
            if (results == null)
            {
                response = new HttpResponseMessage(HttpStatusCode.NotFound);
            }
            else
            {
                response = Request.CreateResponse(HttpStatusCode.OK, results);
            }
            return response;
        }

I don't see how I can pass additional lambdas from the A controller to get the Cs in B loaded. I can see how to do this without using a generic repository. I'm open to using OData too, but can't figure out how to do it using this pattern in Web API

I also tried using the DbContext approach and failed:

public class MyContext : DbContext
    {
        public DbSet<A> As { get; set; }
        public DbSet<B> Bs { get; set; }
        public DbSet<C> Cs { get; set; }

        public MyContext()
            : base("MyDBContext")
        {
        }    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<B>().HasRequired(i => i.C);
            Bs.Include(i => i.C);
        }
    }
Was it helpful?

Solution

You do this using single Include call.

_context.A_Repository // where to get from
    .Include(a => a.Bs.Select(b => b.Cs.Ds.Es)) // what to include
    .Where(a => a.IsCool == true) // how to filter
    .ToList(); // materialize result

See remarks of EntityFramework documentation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top