Search code examples
vb.netmodelasp.net-mvc-5pagingentity-framework-6.1

Unable to get a total count of items in the model in the ASP.NET MVC view


I am using the following code to render a pager:

@Html.BootstrapPager(Request.QueryString("Page"), Function(index) Url.Action("Index", "Posts", New With {.page = index}), 14000, System.Web.Configuration.WebConfigurationManager.AppSettings("PageSize"), 15)

My problem is that If I use Model.Count in place of the 14000 then I only get 1 page of records since I am using skip and take in the repository to pull only the need records. How can i in the view access the total number of published records so that I don't have to hard code the value into the view right now?

The original pager code is here. I converted it to VBNET am using it. It works fine if the record count is hardcoded.

This is the repo:

Dim posts As IEnumerable(Of PostSummaryDTO)
        Using db As BetterBlogContext = New BetterBlogContext
            posts = db.be_Posts.OrderByDescending(Function(x) x.DateCreated).Select(Function(s) New PostSummaryDTO With {.Id = s.PostRowID, .PostDateCreated = s.DateCreated, .PostSummary = s.Description, .PostTitle = s.Title, .IsPublished = s.IsPublished}).Skip((Page - 1) * PageSize).Take(PageSize).ToList()
            Return posts.ToList
        End Using

Solution

  • You need two different methods in the lower layer - one to get the total count and one to get the desired page - and then call them both from your controller, passing both results in the model to the view. As such, the model cannot be a collection of records; it must be an object with a property for a collection of records and a property for the count. Either that or use the ViewBag to pass the count.

    What we do in my office is have a service layer to contain the business logic and repository to handle the data access. There is a single method in the repository to return an IQueryable that provides access to all the records for a particular table. There are then one or more methods in the service that call that repository method and use it in different ways. In this case, there might be a GetTotalCount method and a GetPage method in the service. Both would call the same repository method to get the same IQueryable and then the first method would call Count on the result while the second method would call Skip and Take. As Skip and Take don't force execution of the query, you'd also call ToArray or the like in that second method. The service might also have a GetRecord method that you would pass an ID and call FirstOrDefault inside to get a single record with a matching ID. You can roll the service and repository into a single class if you want but I'd recommend separating the business logic from the data access.