Luca C.
Luca C.

Reputation: 305

Querying related entities with Eager & Explicit loading it doesn't work in EF for ASP.NET MVC CORE

I tried this in VS 2015 .net MVC Application and it works perfectly without any trouble.

Instead, trying to test the same with DOTNET CORE 1.x, I can't get the 2^ level navigation property . You've got a situation like that or you know how solve?

DATABASE CLASS

 public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }

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

    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }

        public Person Person { get; set; }  

        public Blog Blog { get; set; }
    }

    public class Person
    {
        public int PersonId { get; set; }
        public string Username { get; set; }   // I need to show this in the partial view
        public string Action { get; set; }
    }

CONTROLLER

     public async Task<IActionResult> Details(int? id)
    {
        if (id == null)
        {
            return NotFound();
        }


        Blog blog = await _context.Blogs
            .Include(b=>b.Posts)
            .Include(b=>b.Posts.Select(x=>x.Person))    
            .FirstOrDefaultAsync(b => b.BlogId == id);

            //Then.Include  don't show property!


        if (blog == null)
        {
            return NotFound();
        }

        return View(blog);
    }

VIEW

@model MyProj.Models.Blog

@{
    ViewBag.Title = "Details";
}

<h2>Details</h2>

<div>
    <h4>Blog</h4>
    <hr />
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor(model => model.Url)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Url)
        </dd>

    </dl>
</div>
<p>
    @Html.ActionLink("Edit", "Edit", new { id = Model.BlogId }) |
    @Html.ActionLink("Back to List", "Index")
</p>
<br />
<div>
    @Html.Partial("_posts", this.Model.Posts)
</div>

PARTIAL VIEW

@model IEnumerable<MyProj.Models.Post>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Title)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Content)
        </th>
        <th>
            Person
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Title)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Content)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Person.Username)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.PostId }) |
            @Html.ActionLink("Details", "Details", new { id=item.PostId }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.PostId })
        </td>
    </tr>
}

</table>

In my case I cannot get the property Person.Username in a partial that show post list. ThenIclude (with intellisense) don't show the table

Error code : InvalidOperationException: The property expression 'b => {from Post x in [b].Posts select [x].Person}' is not valid. The expression should represent a property access: 't => t.MyProperty'. For more information on including related data, see http://go.microsoft.com/fwlink/?LinkID=746393.

Thanks in advance for troubleshooting, I can't figure it out.

Upvotes: 2

Views: 667

Answers (1)

Luca C.
Luca C.

Reputation: 305

I tried to solve this for about 20 hours to understand why it doesn't work..... At end it was egg of Columbus. Thanks to Ivan Stoev for the comment.

Though intellisense doesn't show the related entities, when the app is builded it works.

 Blog blog = await _context.Blogs
            .Include(b=>b.Posts)
                .ThenInclude(p=>p.Person)  
            .FirstOrDefaultAsync(b => b.BlogId == id);

Upvotes: 4

Related Questions