Why would we want to do this?
- We may want to return a few columns from an entity
- We want to return Json from an MVC view which just gets thrown away
- We want to cut down the amount of code that just handles redundant DTO's because we want to pass data around
The solution to this is really easy (thanks Filip), first we create an anonymous type inline and then project straight into this using an extension method .ListAs(dto)
//first create our anonymous type DTO var dto = new { Id = 0L, Source = string.Empty, Destination = string.Empty, Is301 = false }; //notice the ListAs(dto) extension method var model = Session.QueryOver<CmsRedirect>() .SelectList(s => s .Select(x => x.Id).WithAlias(() => dto.Id) .Select(x => x.Source).WithAlias(() => dto.Source) .Select(x => x.Destination).WithAlias(() => dto.Destination) .Select(x => x.Do301).WithAlias(() => dto.Is301) ) .Take(take).Skip(page * pageSize) .ListAs(dto); return Json(new { Total = total, List = model }, JsonRequestBehavior.AllowGet);The source to the GIST can be found here.
public static class NHibernateExtensions { public static IList<TRes> ListAs<TRes>( this IQueryOver qry, TRes resultByExample) { var ctor = typeof(TRes).GetConstructors().First(); return qry.UnderlyingCriteria .SetResultTransformer( Transformers.AliasToBeanConstructor( (ConstructorInfo) ctor) ).List<TRes>(); } }And the Json that gets returned is:-
{ "Total":3, "List":[ {"Id":101000,"Source":"clients.aspx", "Destination":"portfolio","Is301":true}, {"Id":101101,"Source":"consultancy.aspx", "Destination":"consultancy","Is301":true}, {"Id":101102,"Source":"contact.aspx", "Destination":"contact","Is301":true}, ] }This is perfect for plugging straight into my Kendo UI Grid.
A big thank you to Filip for taking some of the repetiveness out of my day.
No comments:
Post a Comment