efcore: EF CORE 1.1.0 String Based Include not working as expected

RESOLVED - Problem was with LinqKit 1,1,7,3

For versions prior to EF CORE 1.1.0 @rowanmiller provided an excellent workaround for a string based include function which allowed me to do this in my core repository:

//get the data set
var results = Context.Set<TEntity>().AsQueryable(); 

//loop through a list of navigationproperties string paths from properties marked by include attribute
//and generically include them
//example for results of  GetEntityIncludeList() for my Person Entity: 
//Organization, Organization.Address, Manager, Manager.Organisation ... 
foreach (var include in GetEntityIncludeList()) 
{
    results = results**_.Include(include);_**
}
//return the query
return FindQueryExpression(primaryKey.ToArray())
                .Aggregate(results, (current, expression) => current.Where(expression).AsQueryable());

And that worked perfectly.

The issue

When I upgraded to EF Version 1.1.0 I had to remove my IQueryable Extension based on Rowans’ workaround, because now the string based Include function is implemented.

However, it only works when invoked directly on the DBSet<>, like in the following example:

var result =  Context.Set<TEntity>()
      .Include("Organisation")
     .Include("Organisation.Address").Where(w=>w.Id == 1);

This would work. However looping as in the example above doesn’t work.

In my judgement the Include(string) is useless if you can’t use it in this generic fashion. For the time being I had to roll back to EF CORE 1.0.1 as I have found no way to make this work.

I am not sure if it is implemented as is on purpose, for me it could be a bug (I hope it is)

Further technical details

EF Core version: 1.1.0 Operating system: Windows 10 Visual Studio version: VS2015

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 15 (6 by maintainers)

Most upvoted comments

@ctonger I wrote this console app in an attempt to reproduce what you are seeing, but it seems to work fine. Can you look at it and see if you can get your issue to repro using it? Or provide a different complete repro?

public class Blog
{
    public int Id { get; set; }

    public ICollection<Post> Posts { get; set; }
}

public class Post
{
    public int Id { get; set; }

    public int BlogId { get; set; }
    public Blog Blog { get; set; }

    public ICollection<Comment> Comments { get; set; }
}

public class Comment
{
    public int Id { get; set; }

    public int PostId { get; set; }
    public Post Post { get; set; }
}

public class BlogContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(
            @"Server=(localdb)\mssqllocaldb;Database=CollectionsTest;Trusted_Connection=True;ConnectRetryCount=0");
    }
}

public class Program
{
    private static void Main()
    {
        using (var context = new BlogContext())
        {
            context.Database.EnsureDeleted();
            context.Database.EnsureCreated();

            var blog = new Blog();

            for (var i = 0; i < 3; i++)
            {
                var post = new Post {Blog = blog};

                for (var j = 0; j < 3; j++)
                {
                    context.Add(new Comment {Post = post});
                }
            }

            context.SaveChanges();
        }

        using (var context = new BlogContext())
        {
            var query = context.Set<Post>().AsQueryable();

            query = query.Include("Blog");
            query = query.Include("Comments");

            foreach (var post in query)
            {
                Console.WriteLine("Post: {0} on Blog: {1}", post.Id, post.Blog.Id);
                foreach (var comment in post.Comments)
                {
                    Console.WriteLine("    Comment: {0}", comment.Id);
                }
            }
        }
    }
}

@ctonger When you say, “it only works when invoked directly on the DBSet<>, it doesn’t work on the IQueryable,” can you provide more details of how it doesn’t work? Does it throw, in which case can you provider an exception message and stack trace? Does it not compile, in which case what is the compiler error? Or does it return the wrong data, in which case how is the data wrong?