Grid custom querying

The default scenario is that you give an IQueryable to the GridModelBuilder and it will sort it and page it using .OrderBy and .Skip/.Take, this works ok on EntityFramework, but if you're doing something like sql procedures, service calls etc. you might want to do this sorting and paging yourself.

Sorting rules and current page are in the GridParams {SortNames[], SortDirections[], Page} parameter and to tell the GridModelBuilder not to do any querying you have to set the PageCount parameter on it. (grouping doesn't require any querying)

GridCustomQuerying.aspx
<% CustomQueryingGrid.Grid()
.Url(Page.Url().Action("GetItems", "CustomQueryingGrid"))
.Height(450)
.Columns(
new Column { Bind = "Id", Groupable = false, Sortable = false, Width = 70 },
new Column { Bind = "Person" },
new Column { Bind = "Dish.Name" }); %>
<awe:Ocon runat="server" ID="CustomQueryingGrid" />
Demos/Grid/CustomQueryingGridController.cs
using System;
using System.Linq;
using AwesomeWebFormsDemo.Data;
using AwesomeWebFormsDemo.Models;
using System.Web.Mvc;

using Omu.AwesomeWebForms;


namespace AwesomeWebFormsDemo.Controllers.Demos.Grid
{
public class CustomQueryingGridController : Controller
{
public ActionResult GetItems(GridParams g)
{
var pageSize = g.PageSize;
var query = Db.Lunches.AsQueryable();

if (g.SortNames != null)
{
IOrderedQueryable<Lunch> orderedItems = null;

// doing this for demo purposes
// one might use something like Dynamic Linq
// or generate a sql string etc.

for (int i = 0; i < g.SortNames.Length; i++)
{
var column = g.SortNames[i];
var direction = g.SortDirections[i];

if (i == 0)
{
if (column == "Person")
orderedItems = direction == "asc"
? query.OrderBy(o => o.Person)
: query.OrderByDescending(o => o.Person);
else if (column == "Dish.Name")
orderedItems = direction == "asc"
? query.OrderBy(o => o.Dish.Name)
: query.OrderByDescending(o => o.Dish.Name);
}
else
{
if (column == "Person")
orderedItems = direction == "asc"
? orderedItems.ThenBy(o => o.Person)
: orderedItems.ThenByDescending(o => o.Person);
else if (column == "Dish.Name")
orderedItems = direction == "asc"
? orderedItems.ThenBy(o => o.Dish.Name)
: orderedItems.ThenByDescending(o => o.Dish.Name);
}
}

query = orderedItems;
}

var itemsCount = query.Count();
var pageItems = query.Skip((g.Page - 1) * pageSize).Take(pageSize).ToArray();

return Json(new GridModelBuilder<Lunch>(g)
{
KeyProp = o => o.Id,
Map = o => new { o.Id, o.Person, DishName = o.Dish.Name },
ItemsCount = itemsCount,
PageItems = pageItems
}.Build());
}

public ActionResult GetEfAsyncItems(GridParams g)
{
var query = Db.Lunches.AsQueryable();

var gmb = new GridModelBuilder<Lunch>(g)
{
KeyProp = o => o.Id,
Map = o => new { o.Id, o.Person, DishName = o.Dish.Name }
};

// change OrderByFunc if necessary, e.g. if Column.Bind values don't match Lunch Properties names
//gmb.OrderByFunc = (q, rules) => { return q; };

// apply OrderBy according to GridParams
query = gmb.OrderBy(query);

// g.Key is set when calling api.update(id); not used in this demo
if (g.Key != null)
{
var item = Db.Find<Lunch>(Convert.ToInt32(g.Key));
gmb.GetItem = () => item;
}
else
{
gmb.ItemsCount = query.Count();
gmb.PageItems = gmb.GetPage(query).ToArray();
}

return this.AweJson(gmb.Build());
}
}
}



Comments