score:13
i modified the code as follow:
viewmodel
using system.collections.generic;
using contosouniversity.models;
namespace contosouniversity.viewmodels
{
public class instructorindexdata
{
public pagedlist.ipagedlist<instructor> instructors { get; set; }
public pagedlist.ipagedlist<course> courses { get; set; }
public pagedlist.ipagedlist<enrollment> enrollments { get; set; }
}
}
controller
public actionresult index(int? id, int? courseid,int? instructorpage,int? coursepage,int? enrollmentpage)
{
int instructpagenumber = (instructorpage?? 1);
int coursepagenumber = (coursepage?? 1);
int enrollmentpagenumber = (enrollmentpage?? 1);
var viewmodel = new instructorindexdata();
viewmodel.instructors = db.instructors
.include(i => i.officeassignment)
.include(i => i.courses.select(c => c.department))
.orderby(i => i.lastname).topagedlist(instructpagenumber,5);
if (id != null)
{
viewbag.instructorid = id.value;
viewmodel.courses = viewmodel.instructors.where(
i => i.id == id.value).single().courses.topagedlist(coursepagenumber,5);
}
if (courseid != null)
{
viewbag.courseid = courseid.value;
viewmodel.enrollments = viewmodel.courses.where(
x => x.courseid == courseid).single().enrollments.topagedlist(enrollmentpagenumber,5);
}
return view(viewmodel);
}
view
<div>
page @(model.instructors.pagecount < model.instructors.pagenumber ? 0 : model.instructors.pagenumber) of @model.instructors.pagecount
@html.pagedlistpager(model.instructors, page => url.action("index", new {instructorpage=page}))
</div>
i hope this would help you!!
score:1
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 a viewbag
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 chose instructors
:
viewbag.onepageofitems = myviewmodelinstance.instructors.topagedlist(pagenumber, 10);
then, the rest of the standard code works as it always has.
score:3
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:
int pagesize = 4;
int pagenumber = (page ?? 1);
//used the following two formulas so that it doesn't round down on the returned integer
decimal totalpages = ((decimal)(viewmodel.teachers.count() /(decimal) pagesize));
viewbag.totalpages = math.ceiling(totalpages);
//these next two functions could maybe be reduced to one function....would require some testing and building
viewmodel.teachers = viewmodel.teachers.topagedlist(pagenumber, pagesize);
viewbag.onepageofteachers = viewmodel.teachers;
viewbag.pagenumber = pagenumber;
return view(viewmodel);
i added
using.pagedlist;
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.
@model cshm.viewmodels.teacherindexdata
@using pagedlist;
@using pagedlist.mvc;
<link href="~/content/pagedlist.css" rel="stylesheet" type="text/css" />
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.
page @viewbag.pagenumber of @viewbag.totalpages
@html.pagedlistpager((ipagedlist)viewbag.onepageofteachers, page => url.action("index", new { page }))
hope that works for you. let me know if it works!!
score:16
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.)
public class questionviewmodel
{
public int questionid { get; set; }
public string questionname { get; set; }
}
and the index method of your controller will be something like
public actionresult index(int? page)
{
var questions = new[] {
new questionviewmodel { questionid = 1, questionname = "question 1" },
new questionviewmodel { questionid = 1, questionname = "question 2" },
new questionviewmodel { questionid = 1, questionname = "question 3" },
new questionviewmodel { questionid = 1, questionname = "question 4" }
};
int pagesize = 3;
int pagenumber = (page ?? 1);
return view(questions.topagedlist(pagenumber, pagesize));
}
and your index view
@model pagedlist.ipagedlist<viewmodel.questionviewmodel>
@using pagedlist.mvc;
<link href="/content/pagedlist.css" rel="stylesheet" type="text/css" />
<table>
@foreach (var item in model) {
<tr>
<td>
@html.displayfor(modelitem => item.questionid)
</td>
<td>
@html.displayfor(modelitem => item.questionname)
</td>
</tr>
}
</table>
<br />
page @(model.pagecount < model.pagenumber ? 0 : model.pagenumber) of @model.pagecount
@html.pagedlistpager( model, page => url.action("index", new { page }) )
here is the so link with my answer that has the step by step guide on how you can use pagelist
score:29
for anyone who is trying to do it without modifying your viewmodels and not loading all your records from the database.
repository
public list<order> getorderpage(int page, int itemsperpage, out int totalcount)
{
list<order> orders = new list<order>();
using (databasecontext db = new databasecontext())
{
orders = (from o in db.orders
orderby o.date descending //use orderby, otherwise skip will throw an error
select o)
.skip(itemsperpage * page).take(itemsperpage)
.tolist();
totalcount = db.orders.count();//return the number of pages
}
return orders;//the query is now already executed, it is a subset of all the orders.
}
controller
public actionresult index(int? page)
{
int pagenumber = (page ?? 1) -1; //i know what you're thinking, don't put it on 0 :)
ordermanagement orderman = new ordermanagement(httpcontext.applicationinstance.context);
int totalcount = 0;
list<order> orders = orderman.getorderpage(pagenumber, 5, out totalcount);
list<orderviewmodel> orderviews = new list<orderviewmodel>();
foreach(order order in orders)//convert your models to some view models.
{
orderviews.add(orderman.generateorderviewmodel(order));
}
//create staticpagelist, defining your viewmodel, current page, page size and total number of pages.
ipagedlist<orderviewmodel> pageorders = new staticpagedlist<orderviewmodel>(orderviews, pagenumber + 1, 5, totalcount);
return view(pageorders);
}
view
@using pagedlist.mvc;
@using pagedlist;
@model ipagedlist<babywatcher.core.models.orderviewmodel>
@{
viewbag.title = "index";
}
<h2>index</h2>
<div class="container-fluid">
<p>
@html.actionlink("create new", "create")
</p>
@if (model.count > 0)
{
<table class="table">
<tr>
<th>
@html.displaynamefor(model => model.first().orderid)
</th>
<!--rest of your stuff-->
</table>
}
else
{
<p>no orders yet.</p>
}
@html.pagedlistpager(model, page => url.action("index", new { page }))
</div>
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:
public static ordermodel converttomodel(order entity)
{
if (entity == null) return null;
ordermodel model = new ordermodel
{
contactid = entity.contactid,
orderid = entity.orderid,
}
return model;
}
below your repository class, add this:
public static partial class ex
{
public static ienumerable<ordermodel> selectordermodel(this ienumerable<order> source)
{
bool includerelations = source.gettype() != typeof(dbquery<order>);
return source.select(x => new ordermodel
{
orderid = x.orderid,
//example use converttomodel of some other repository
billingaddress = includerelations ? addressrepository.converttomodel(x.billingaddress) : null,
//example use another extension of some other repository
shipments = includerelations && x.shipments != null ? x.shipments.selectshipmentmodel() : null
});
}
}
and then in your getorderpage
method:
public ienumerable<ordermodel> getorderpage(int page, int itemsperpage, string searchstring, string sortorder, int? partnerid,
out int totalcount)
{
iqueryable<order> query = dbcontext.orders; //get queryable from db
.....//do your filtering, sorting, paging (do not use .tolist() yet)
return queryorders.selectordermodel().asenumerable();
//or, if you want to include relations
return queryorders.include(x => x.billingaddress).tolist().selectordermodel();
//notice difference, first tolist(), then selectordermodel().
}
let me explain:
the static converttomodel
method can be accessed by any other repository, as used above, i use converttomodel
from some addressrepository
.
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 the source
is not a database query type (not an linq-to-sql iqueryable
). 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. the inlcuderelations
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.
Source: stackoverflow.com
Related Query
- ASP NET MVC Error construction INSERT with FOREIGN KEY
- Display image file from database using Entities Asp Net MVC C#
- Add content to every view or component in ASP NET MVC
- How To Post Multiple Objects from View To dot net core 6 MVC Controller using ajax jquery
- Display a warning alert from between date using C# ASP NET
- Net 5 unit test with multiple using httpClientFactory
- End To End Encrypted Chat Application using Windows Forms and . Net C#. Where do I start with encryption?
- Where do you store the ViewModel in MVC using .NET Core?
- Add a search bar in asp net mvc
- Multi page scanning twain using asp net framework 4.7.2
- How to handle errors with exception filter while deploying ASP .NET Core 5 application using Linux Docker containers?
- Multiple models in one view - login & register using ViewModel - with field & ModelState validation
- Populate (Bind) DropDownList from ViewModel in ASP.Net MVC using MySql
- ASP NET 5 - Custom Authentication scheme handler is ignored when using Identity
- asp net core edit with list of base types
- Activating classes with hangfire in ASP Net Core
- Intermittent "Key not valid for use in specified state" exceptions using DPAPI with IIS and ASP.NET MVC using CurrentUser
- ASP NET Core MVC how to display data from SQL table in List Razor Template by UserID foreign key
- not able to fetch and post data with angular js using asp.net core mvc
- How can i hide the query string from the url using asp. Net mvc
- Display Marker Using Latitude And Longitude From SQL Database With Leaflet Map In ASP.NET CORE MVC
- ASP NET API - Authenticate users using Azure AD SAML Protocol without open Microsoft Login Page
- Google Two Factor Authentication with Asp .Net MVC
- Not Able to Upload 2 Kb File Properly Using IFromFile object In ASP Dot net Core 3.1
- Using 2 submit button in a same row with different function in MVC
- How to set up default value for Null Type in Kendo UI asp net MVC
- ASP NET MVC - Can't register and log in
- How to resolve HttpPut Error 405 in ASP NET Core 3.1 MVC project?
- AJAX call to WebAPI Get method with Parameters not downloading file ASP .NET MVC
- foreignkey relationships not appear in edmx with mysql database with asp mvc with database first
More Query from same tag
- C# console app won't send UDP multicast packet on Windows Server 2003
- TPL return value and exception
- How to Convert ListView to Datatable in WPF?
- ASP.NET Core read config IOptions controller not triggering
- How to solve "Request Header Too Long" on an Azure Web App
- Finding node using HTML agility pack
- Using Yield to make a function wait until something is true Unity C#
- Handling special characters in query string
- sql statement based on mulitple drop down selection
- navigate to page in user control (metro app win8)
- How to mock a service call with a lambda expression using Moq
- How to I pass the database file name through one form to another
- Display database result as XML
- Error Calling a JAVA web service after Windows Update KB3147458
- How can I retrieve multiple last_insert_rows in SQLite?
- Playlist in Windows 8 app
- How to properly use London time regardless of BST/GMT
- WPF Image won't update programmatically
- Change 'Show location of pointer when I press the Ctrl key' Windows setting from code
- Store a list<string> to SQL database table?
- Write text filename as date in c#
- Get Image as a response from HttpWebRequest in HttpHandler
- How to get design time data in silverlight/wpf designer?
- Showing Message Box in VS C# 2010
- column header text changes after change DataSource?
- prefix linq2sql entities
- Suggestion query taking long time
- How to design the grid view with multiple row in on row template
- Dynamically changing receive buffer size for sockets
- StateHasChanged not updating component