1

I'm writing an entity framework query which needs Eager loading multiple levels based on condition.

var blogs1 = context.Blogs
    .Include(x => x.Posts.FirstOrDefault(h => h.Author == "Me"))
    .Include(x => x.Comment)
    .FirstOrDefault();

public class Blog
{
    public int BlogId { get; set; }
    public virtual ICollection<Post> Posts { get; set; }
}


public class Post
{
    public int PostId { get; set; }
    public string Author { get; set; }  
    public int BlogId { get; set; }
    public virtual ICollection<Comment> Comments { get; set; }
}

public class Comment
{
    public int PostId
    public int CommentId { get; set; }
    public string CommentValue { get; set;}
}
var blogs2 = context.Blogs
                        .Include("Posts.Comments")
                        .ToList(); 

I expect result to have first or default Blog and first or default Post for that blog by author "Me" and a list of all comments.

When query for blogs1is executed I see following exception blogs2 query works as expected

The Include path expression must refer to a navigation property defined on the type. Use dotted paths for reference navigation properties and the Select operator for collection navigation properties. Parameter name: path

Krtti
  • 62
  • 10
  • 1
    Have you tried to use Include(d=>d.Posts).Include(d=>Posts.Comments).ToList()? – Moe Jallaq Oct 11 '19 at 19:45
  • so, Posts looks like it is a navigation property on Blog object, but i dont see a Comment property on Blog object. I would think this is your offending line based on the code you presented ".Include(x => x.Comment)" since I am assuming that your Blog object does not have a navigation property called "Comment" – victor Oct 11 '19 at 19:45
  • @MoeJallaq my requirement was to filter based on Posts and to do first or deafault – Krtti Oct 18 '19 at 20:19
  • @victor Update question, Comment is actually navigation property on Post – Krtti Oct 18 '19 at 20:20
  • @Rufus L this question is not duplicate, my requirement is conditional include with navigation property, that is I want to filter on Blog , Posts and need all comments for the first or default post – Krtti Oct 18 '19 at 20:25

1 Answers1

1

FirstOrDefault executes the query and you can not use it inside Include as its purpose is to include navigational properties. You will need to modify the query to one of the below two ways:

Method 1: Its two two step process:

var blogs1 = context.Blogs
    .Include(x => x.Posts.Select(p => p.Comments))
**//     .Include(x => x.Comment) // This include is incorrect.**
    .FirstOrDefault(x => x.Posts.Any(h => h.Author == "Me"));

var myPosts = blogs1?.Posts.Where(p => p.Author == "Me");

Method 2:

var myPosts = context.Posts.Include(p => p.Blog).Include(p => p.Comments).Where(p => p.Author == "Me");
sam
  • 1,937
  • 1
  • 8
  • 14
  • Thanks for response, I actually used second method in my code. But actually I was wondering how could I do the same using Method 1 with out getting all Post's related to Blog from database. – Krtti Oct 20 '19 at 17:54
  • I used Method 2 with FirstOrDefault rather than Where, as per my requirement. – Krtti Oct 20 '19 at 18:03
  • Using Method 1, its not possible to pull just the post. – sam Oct 21 '19 at 13:16
  • Yes Sam, I figured that out. Thanks for answering. – Krtti Nov 18 '19 at 21:54