Awesome ASP.net Core and MVC Controls

Grid custom querying

By default the GridModelBuilder will query the data (order and get page), but you can to that yourself and pass the ordered and paged data. You might need to do that if you're using stored procedures, service calls, or any other data storage tech that doesn't support linq.
You might also want to load the data using async/await methods and only after that pass it to the GridModelBuilder, and for this scenario the GridModelBuilder has methods to apply the OrderBy and Page on your query before you call your Async Load method, see examples below.

Manually ordering and paging data


Here we are showing how we could query the data manually before passing it to the GridModelBuilder. One could also use something like Dynamic Linq or generate a sql script etc.
GridDemo/CustomQuerying.cshtml
@(Html.Awe().Grid("CustomQueryingGrid")
.Url(Url.Action("GetItems", "CustomQueryingGrid"))
.Height(300)
.Columns(
new Column { Bind = "Id", Groupable = false, Sortable = false, Width = 70 },
new Column { Bind = "Person" },
new Column { Bind = "Food" }))
Demos/Grid/CustomQueryingGridController.cs
public ActionResult GetItems(GridParams g)
{
var pageSize = g.PageSize;
var items = 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"
? items.OrderBy(o => o.Person)
: items.OrderByDescending(o => o.Person);
else if (column == "Food")
orderedItems = direction == "asc"
? items.OrderBy(o => o.Food)
: items.OrderByDescending(o => o.Food);
}
else
{
if (column == "Person")
orderedItems = direction == "asc"
? orderedItems.ThenBy(o => o.Person)
: orderedItems.ThenByDescending(o => o.Person);
else if (column == "Food")
orderedItems = direction == "asc"
? orderedItems.ThenBy(o => o.Food)
: orderedItems.ThenByDescending(o => o.Food);
}
}

items = orderedItems;
}

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

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

Execute async query before building model


In this grid we are fetching the data before calling GridModelBuilder.Build, this way you could use an async call to fetch data, await for the call and after pass the items and count to the GridModelBuilder.
GridDemo/CustomQuerying.cshtml
@(Html.Awe().Grid("GridQuery2")
.Url(Url.Action("GetEfAsyncItems", "CustomQueryingGrid"))
.Height(300)
.Columns(
new Column { Bind = "Id", Groupable = false, Sortable = false, Width = 70 },
new Column { Bind = "Person" },
new Column { Bind = "Food" }))
Demos/Grid/CustomQueryingGridController.cs
public async Task<ActionResult> GetEfAsyncItems(GridParams g)
{
var items = Db.Lunches.AsQueryable();

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

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

// g.Key is set when calling api.update(id)
if (g.Key != null)
{
var item = await Db.GetAsync<Lunch>(Convert.ToInt32(g.Key));
gmb.GetItem = () => item;
}
else
{
gmb.ItemsCount = await items.CountAsync();
gmb.PageItems = await gmb.GetPage(items).ToArrayAsync();
}

return Json(gmb.Build());
}



Comments