I'm trying to using a PagedList in my ASP.Net application and I found this example on the Microsoft website http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application
How is it possible to use a PagedList in a complex situation that uses a ViewModel? I'm trying to add a PagedList without success to the Instructor example posted here: http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/reading-related-data-with-the-entity-framework-in-an-asp-net-mvc-application
The problem is that the ViewModel is composed by classes and not simple fields, so I cannot convert the result with the ToPageList() method.
This is the ViewModel structure:
using System.Collections.Generic;
using ContosoUniversity.Models;
namespace ContosoUniversity.ViewModels
{
public class InstructorIndexData
{
public IEnumerable<Instructor> Instructors { get; set; }
public IEnumerable<Course> Courses { get; set; }
public IEnumerable<Enrollment> Enrollments { get; set; }
}
}
I need to join the three tables into the ViewModel and display the result in a View.
For anyone who is trying to do it without modifying your ViewModels AND not loading all your records from the database.
Repository
Controller
View
Bonus
Do above first, then perhaps use this!
Since this question is about (view) models, I'm going to give away a little solution for you that will not only be useful for paging, but for the rest of your application if you want to keep your entities separate, only used in the repository, and have the rest of the application deal with models (which can be used as view models).
Repository
In your order repository (in my case), add a static method to convert a model:
Below your repository class, add this:
And then in your
GetOrderPage
method:Let me explain:
The static
ConvertToModel
method can be accessed by any other repository, as used above, I useConvertToModel
from someAddressRepository
.The extension class/method lets you convert an entity to a model. This can be IQueryable or any other list, collection.
Now here comes the magic: If you have executed the query BEFORE calling
SelectOrderModel()
extension,includeRelations
inside the extension will be true because thesource
is NOT a database query type (not an linq-to-sqlIQueryable
). When this is true, the extension can call other methods/extensions throughout your application for converting models.Now on the other side: You can first execute the extension and then continue doing LINQ filtering. The filtering will happen in the database eventually, because you did not do a
.ToList()
yet, the extension is just an layer of dealing with your queries. Linq-to-sql will eventually know what filtering to apply in the Database. TheinlcudeRelations
will be false so that it doesn't call other c# methods that SQL doesn't understand.It looks complicated at first, extensions might be something new, but it's really useful. Eventually when you have set this up for all repositories, simply an
.Include()
extra will load the relations.As Chris suggested the reason you're using ViewModel doesn't stop you from using
PagedList
. You need to form a collection of your ViewModel objects that needs to be send to the view for paging over.Here is a step by step guide on how you can use
PagedList
for your viewmodel data.Your viewmodel (I have taken a simple example for brevity and you can easily modify it to fit your needs.)
and the Index method of your controller will be something like
And your Index view
Here is the SO link with my answer that has the step by step guide on how you can use
PageList
The fact that you're using a view model has no bearing. The standard way of using
PagedList
is to store "one page of items" as aViewBag
variable. All you have to determine is what collection constitutes what you'll be paging over. You can't logically page multiple collections at the same time, so assuming you choseInstructors
:Then, the rest of the standard code works as it always has.
I figured out how to do this. I was building an application very similar to the example/tutorial you discussed in your original question.
Here's a snippet of the code that worked for me:
I added
to my controller as the tutorial states.
Now in my view my using statements etc at the top, NOTE i didnt change my using model statement.
and then at the bottom to build my paged list I used the following and it seems to work. I haven't yet built in the functionality for current sort, showing related data, filters, etc but i dont think it will be that difficult.
Hope that works for you. Let me know if it works!!
I modified the code as follow:
ViewModel
Controller
View
I hope this would help you!!