theKindOfMe

February 27, 2009

EntitySqlException: “The ORDER BY sort key(s) type must be order-comparable.”

Filed under: Uncategorized — Tags: , , , — yasi8h @ 8:42 am

Think: In the Entity Framework…

you have two models like this:

Item{ID, Name, Category}, Category{ID, Name}

With a Relationship like this:

Item belongs to a Category. and a Category may have zero or more Items.

if you try to sort the Items by their Category(which doesn’t make sense in the first place! :P) by doing something like:

YourObjectContext.Items.OrderBy(“it.Category”)

you would get the error that is specified in the title of this post. .

but if all you want to do is sort all the Items by the Name of their respective Categories. you should do something like this:

YourObjectContext.Items.OrderBy(“it.Category.Name”)

it will work just fine. you can use this doted notation to specify properties of properties(nested properties). this can be used with OrderBy’s Where caluses…etc this is a faily simple thing i know 🙂 but it was bit tricky to find this out, for me atleast.

February 16, 2009

Reawakening of my inner linux ‘freak’ – Moving into Arch Linux

Filed under: Uncategorized — Tags: , , , — yasi8h @ 6:13 pm
arch linux - kde - yakuake

arch linux - kde - yakuake

Background

I’ve been using linux for like 4 years now. in the beginning i was just trying it out. back then i used almost any thing i could find. redhat/knoppix/suse/debian…etc but back then i was only trying them out. but for the last one/two year(s) I’ve been with ubuntu. the reasons were simple. it just worked! but recently i felt so bored with my system. so last weekend i download a Arch iso and started installing the distro.

Why Arch Linux

  • simple
  • packages are build for i686, thus they will be more optimized(good for my ‘old’ laptop)
  • pacman is good(I’m a huge fan of apt, so a good package manager was a must)
  • good documentation/support/community
  • i can choose what i want to install, i have control over what’s getting into my system. ie: the system is really ‘mine’ when its done.
arch linux kde desktop

arch linux kde desktop

Installation

i read a bit of the beginners guide available in the Arch Wiki. but soon got bored 😛 so i followed along the installation script. it was pretty straight forward. but i wanted to use ext4 as my root file system. as i was trying out a new distro. i figured this is the best time to try out the new file system. after all there was a lot of talk going around about ext4 been much better than ext3(naturally…). i was installing the system on my laptop. which is a bit old. so i thought ext4 would help me with the speed. and after all one of the reasons i choose to go with arch was that all it’s packages were build for i686 platform. which will usually make em run faster.

Arch and Ext4

as of now(16/feb/2009) official arch installing media doesn’t support ext4. meaning you wouldn’t be able to just make a ext4 partition the way you would have made a ext3… because the tools needed for it are not included in the installation media. but its not that hard to get it working. the best way to do is(ASFAIK) installing the system in to a ext3 partition. and then converting the partition(s) ext4. when you need to convert your root partition you have to use a live cd to do it. its pretty straight forward. please refer to the arch wiki for more info.

btw i tried to upgrade the live cd(arch installation media) before installing the system so i could get all the ext4 supported tools..etc but that was too good to be true. it broke the system. and when i tried to get around the broken stuff it eventually lead to a kernel panic! 😛 but its ok. its nice to have experiences right? 🙂

KDE

i am so amazed with the latest release of KDE! it rocks. i have been a gnome(default in ubuntu) user for a while now. never had much time to look at kde. even when i got a chance to work with it. it felt a bit uncomfortable so i never really wanted to try it out. but lately i’ve been more and more curious about KDE. so this time i choose to go with it. wow. it was really nice. its visually appealing. but wait its not the main thing. its rock solid! i have only 512MB ram. but still it works grate. no slow downs or what so ever. i feel good about the way it looks and works. but there are somethings that i am still a bit alien to. but its ok. i am getting used to KDE. its grate. i suggest you give it a try too. you never know, you might like it too.

archlinux - kde - firefox - KFirefox theme

archlinux - kde - firefox - KFirefox theme

Where is Firefox?

i found it a bit hard to believe that firefox is not the default browser in KDE at first when i installed it. but then again konqueror is a decent browser too. anyways i switched to firefox. when you start up firefox you would notice something. that is it looks damn UGLY! i think this is because it is not a kde application. but no worries you can get it to look better by installing KFirefox theme. it gives a nice look. and FF would look much more like a kde app.

kde 4.2 - kickoff application luncher

kde 4.2 - kickoff application launcher

Getting Stuff to Work

unlike ubuntu arch expects you to read stuff and install what you need by your self. its not hard. but it will need some of your time. you will need do some googling at some point or other and find out about things that you need and install them by your self. for example when i tried to connect to my gmail/gtalk account using kopete. it just didn’t work. reading around a bit reviled that it need a SSL library installed in order to work with gtalk. i had to install these libraries by my self. but of course its just a ‘pacman -S package’ away! 🙂

Arch WiKi Rocks!

arch wiki is a very rich source of information when you trying to solve your problems about arch. it will really teach you a lot of things about your system. whenever you want install some package or whenever you want to learn about how to do something in arch. its best to check out the wiki. as it have answers/articles for most your common problems. it will save you a lot of time.

Final Thoughts

i’m kinda happy that i choose to go ahead and install this new distro. i now have a good system running in my laptop. arch linux is a grate distro. you might want to give it a try. its not for everyone. if you don’t won’t to mess with your system and just wants something that just works. go for ubuntu/fedora/mint…etc. but if you want a system that is pretty simple and configurable to your liking. arch is a good choice. you can make a lot of choices when you choose arch. unlike in ubuntu where a lot things are already decided for you(this is good if you just want everything to work…).

February 5, 2009

A Grid with Ajax/Pagination/Sorting/Filtering on ASP.net MVC with ExtJS and Enitiy Framework

Filed under: Uncategorized — Tags: , , , , , , , — yasi8h @ 9:18 am

I am new to all these JS libraries like jQuery and ExtJS(there are many more out there…). when i got started with asp.net mvc i looked in to jQuery. and i was absolutely amazed with all the functionality it offered with very simple and neat syntax! a while ago i did a post on “Ajax Enabling MVCContrib Grid’s Pagination with jQuery”. In which i added AJAX/pagination support to MVCContrib’s Grid. but with time i needed more and more features from the grid. like sorting and filtering(through AJAX of course). then i came across the wonderful JS library called ExtJS. it have grate UI components done and ready to be used. i love all ExtJS stuff that is related to UI. and their components seems to be very extensible as well.

Ext JS Overview

Ext JS is a cross-browser JavaScript library for building rich Internet applications. It includes:

  • High performance, customizable UI widgets
  • Well designed and extensible Component model
  • An intuitive, easy to use API
  • Commercial and Open Source licenses available

i liked there Grid and it had all the features i needed. so i decided to go ahead with it.

extjs_grid_screenshot

the main points i had to look at:

  • including a ExtJS distribution with my asp.net mvc project which is already using jQuery
  • inserting the relevant JS to render the grid in my views
  • creating the necessary controller actions to support the grid’s actions(get data/sort/filter data…etc)

Including a ExtJS distribution

ExtJS JS library can use other libraries(such as jQuery…) as its base library. so been a fan of jQuery, i choose to build a custom version of ExtJS which uses jQuery as its base.  this version of the library includes the jQuery adapter within it self. but you still need to include the jQuery library by your self. it is NOT included in the custom version that you built for your self.  so in your site.master(you can put these where ever you like, not necessary in the site.master. just make sure these are included where ever you use them) you have to include the libraries in the following order: include jQuery first, then include any jQuery plugins you use and finally include ExtJS(any of your custom JS files should be included afterward).

now you are done including the JS libraries necessary . but ExtJS’s UI components need a few more things to be included in your site.master for them to work correctly. you need to include the necessary style sheets/images used by ExtJS components. to get these download ExtJS SDK. this includes all the style sheets and the images among other things. you will need to include the necessary plugins as well.

  • ext-2.2resourcescssext-all.css
  • ext-2.2resourcesimages – images used by ExtJS components
  • all JS files under ext-2.2examplesgrid-filteringgrid – includes necessary plugins needed for the grid filtering functionality

now you are ready to roll. note that we can use what ever jQuery we want when we are working with extjs components. and as we are using the jQuery core(and also because we are already using jQuery in out mvc project) the size of the ExtJS library is much lower.

Rendering the grid

looking at the samples(look under ext-2.2examplesgrid-filtering) included in the extjs sdk. its not that hard to figure out how to render the grid using javascript. the extjs API reference would be helpful as well.

i ran across a bug in the GridView component when i tried to use disable ‘autoHeight’ ‘feature’ of the grid. how ever there was a fix available for it in the the extjs forums.  following is the JS code that i used in my view(in which the grid resides). i just included them in a script tag within the view. but the best way to use them would be to extract them in to some helper methods and then using the helpers.

some notes about ExtJs grids

  • a grid is ‘bound’ to a data store.
  • when rendering a grid you will have to create a data record, column modal and a data reader(JsonReader in this case).
  • column modal – how the columns are structured
  • data record – how a data record(or a person object, in the context of this example) is structured. what fields does it contain…etc
  • data reader – where to get/ how to read data
  • filters and paging is connected to the grid in a ‘pluggable’ manner

        //Sugguested Fix for the bug: "Grid autoHeight disables horizontal scrolling too"
        Ext.override(Ext.grid.GridView, {
            layout: function() {
                if (!this.mainBody) {
                    return;
                }
                var g = this.grid;
                var c = g.getGridEl(), cm = this.cm,
                expandCol = g.autoExpandColumn,
                gv = this;
                var csize = c.getSize(true);
                var vw = csize.width;
                if (vw < 20 || csize.height < 20) {
                    return;
                }
                if (g.autoHeight) {
                    csize.height = this.mainHd.getHeight() + this.mainBody.getHeight();
                    if (!this.forceFit) {
                        csize.height += this.scrollOffset;
                    }
                }
                this.el.setSize(csize.width, csize.height);
                var hdHeight = this.mainHd.getHeight();
                var vh = csize.height - (hdHeight);
                this.scroller.setSize(vw, vh);
                if (this.innerHd) {
                    this.innerHd.style.width = (vw) + 'px';
                }
                if (this.forceFit) {
                    if (this.lastViewWidth != vw) {
                        this.fitColumns(false, false);
                        this.lastViewWidth = vw;
                    }
                } else {
                    this.autoExpand();
                }
                this.onLayout(vw, vh);
            }
        });
        //end bug fix here
        //////////////////

        Ext.onReady(function() {
            Ext.QuickTips.init(); //for enabling tool tips

            Ext.menu.RangeMenu.prototype.icons = {
                gt: '/Scripts/extjs/plugins/grid-filter/img/greater_then.png',
                lt: '/Scripts/extjs/plugins/grid-filter/img/less_then.png',
                eq: '/Scripts/extjs/plugins/grid-filter/img/equals.png'
            };
            Ext.grid.filter.StringFilter.prototype.icon = '/Scripts/extjs/plugins/grid-filter/img/find.png';

            createAndShowGrid();
        });

        function createAndShowGrid() {

            order = Ext.data.Record.create(&#91;
	        { name: 'Id' },
	        { name: 'FirstName' },
	        { name: 'Email' }
        &#93;);

            orderReader = new Ext.data.JsonReader({
                root: 'dataitems',
                totalProperty: 'totalItems' //number of total records
            },
		    order
	    );
            //data store creation
            ds = new Ext.data.Store({
                proxy: new Ext.data.HttpProxy({
                    url: '/Person/ListJson'
                }),
                reader: orderReader,
                sortInfo: { field: 'Id', direction: "ASC" },
                remoteSort: true
            });

            columnModel = new Ext.grid.ColumnModel(&#91;{
                header: 'Person Id',
                dataIndex: 'Id'
            }, {
                header: 'Person Name',
                dataIndex: 'FirstName'
            }, {
                header: 'Person Email',
                dataIndex: 'Email'
            }
	    &#93;);

            columnModel.defaultSortable = true;

            var filters = new Ext.grid.GridFilters({
                filters: &#91;
	                { type: 'string', dataIndex: 'Id' },
	                { type: 'string', dataIndex: 'FirstName' },
	                { type: 'string', dataIndex: 'Email' }
	            &#93;
            });

            var pagingBar = new Ext.PagingToolbar({
                pageSize: 10,
                store: ds,
                displayInfo: true,
                displayMsg: 'Displaying Persons {0} - {1} of {2}',
                emptyMsg: "No Persons to display",
                plugins: filters
            });

            grid = new Ext.grid.GridPanel({
                store: ds,
                cm: columnModel,
                width: 500,
                autoHeight: true,
                title: 'Persons List',
                frame: true,
                loadMask: true,
                stripeRows: true,
                plugins: filters,
                bbar: pagingBar // paging bar on the bottom
            });

            grid.render('personGrid');
            grid.store.load({ params: { start: 0, limit: 10} });
        }
<div id="personGrid"

&#91;/sourcecode&#93;
<h4>Controller actions to support the grid's actions(get data/sort/filter data...etc)</h4>
A ExtJS grid can be fed data in various ways. i am going use a controller action to give the grid the data it needs to render it self. the data would be in json format. we would have a controller action like the following, that returns a JsonResult. we can use the Json method in the mvc framework to serialize the data to json with ease. i am doing it by constructing a anonymous type that hosts the data and then serializing it to json. please note that the following example uses the Entity Framework to deal with the back-end data. although this is example uses the EF. you can easily port it to use any other ORM technology(Linq...etc).

source of /Person/ListJson action


public JsonResult ListJson()
        {
            int totalOjectCount;
            var personsList = ExtJSGridFilterHelper.GetResults(Request, new ObjectEntities().Person,out totalOjectCount);
            var list = new ArrayList();
            foreach (var person in personsList) //populate data containers with read data
            {
                list.Add(new
                             {
                                 Id = person.ID,
                                 FirstName = person.FirstName,
                                 person.Email
                             });
            }
            return Json(new { dataitems = list.ToArray(), totalItems = totalOjectCount });
        }

note that the json result that is returned, basically contains a array of items and a another property called totalItems. this total items property tell the grid, the number of(obviously ) total items that it will have to display. this is helpfule for the grid when pagination is enabled. and you should make sure that this property is specified in your json output if you want the pagination to work correctly.

example json output that is produced by the above action

{"dataitems":[{"Id":"5","FirstName":"jhon Lalic","Email":"jhon@gmail.com"},{"Id":"6","FirstName":"Maureen Joesph","Email"
:"maureen@gmail.com"}],"totalItems":2}

this contains two records. and the totalItems property.

ExtJSGridFilterHelper is a helper class that harbours most of the logic related to implementing sorting/paging and filtering of data. i am not going to explain what the source code is doing, step by step. but you can always read the source ;). 

parsing of parameters sent by the grid…(for the full source code please look at the source of ExtJSGridFilterHelper)

parameters related to paging

  • start
  • limit

parameters related to the sorting

  • sort => the name of the property to be sorted(as given in the client side(aka field name))
  • dir => direction
if (sort != null) //do sorting
            {
                objectsList = query.OrderBy("it." + sort).ToList();
                if (dir == "DESC") objectsList.Reverse();
            }
            else
            {
                objectsList = query.ToList();
            }

parameters related to the filters

public Filter(int id, HttpRequestBase request)
            {
                Id = id;
                Field = request.Params[string.Format("filter[{0}][field]", id)];
                DataType = request.Params[string.Format("filter[{0}][data][type]", id)];
                DataValue = request.Params[string.Format("filter[{0}][data][value]", id)];
                Datacomparison = request.Params[string.Format("filter[{0}][data][comparison]", id)];
            }

how filters are processed, extract from the getExpression() method

</pre>
<pre>public FilterExpressionResult getExpression()
            {
                string expressionString = null;
                var expressionParams = new List(); //paramerters collection
                switch (DataType)
                {
                    case "string":
                        expressionString = string.Format("(it.{0} like '{1}%')", Field, DataValue);
                        break;
                    case "boolean":
                        expressionString = string.Format("(it.{0} = {1})", Field, (DataValue == "true") ? 1 : 0);
                        break;
                    case "numeric":
                        switch (Datacomparison)
                        {
                            case "gt":
                                Datacomparison = ">";
                                break;
                            case "lt":
                                Datacomparison = "";
                                break;
                            case "lt":
                                Datacomparison = "<";
                                break;
                            default:
                                Datacomparison = "=";
                                break;
                        }

                        expressionParams.Add(new ObjectParameter("Param" + Id, DateTime.Parse(DataValue)));
                        expressionString = string.Format("(it.{0} {2} {1})", Field, "@" + "Param" + Id, Datacomparison);
                        break;
                    case "list":
                        var split = DataValue.Split(new&#91;&#93; { ',' });
                        var r = new string&#91;split.Length&#93;;
                        for (var i = 0; i < split.Length; i++)
                        {
                            r&#91;i&#93; = string.Format("(it.{0} = '{1}')", Field, split&#91;i&#93;);
                        }
                        expressionString = string.Format("({0})", string.Join("OR", r));
                        break;
                }
<pre>

source of ExtJSGridFilterHelper

public class ExtJSGridFilterHelper
{
public static List GetResults(HttpRequestBase request, ObjectQuery query, out int totalOjectCount)
{
var sort = request.Params[“sort”];
var dir = request.Params[“dir”];

//get non null values
int intStart, intLimit;
if (!int.TryParse(request.Params[“start”], out intStart)) intStart = 0;
if (!int.TryParse(request.Params[“limit”], out intLimit)) intLimit = 10;

List objectsList;

totalOjectCount = query.Count();
var i = 0;
var exspressions = new List();
var parameters = new List();
while (true) //check for filters starting from 0, if one exists move to the next one(0 -> 1…), .
{
if (!Filter.checkExistence(i, request.Params)) break; //…if not stop looking further
var expression = new Filter(i, request).getExpression();
exspressions.Add(expression.Expression);
parameters.AddRange(expression.Parameters);
i++; //keep track of index
}
var exspression = string.Format(“({0})”, string.Join(“AND”, exspressions.ToArray()));
//build the final expression
if (exspression != “()”) query = query.Where(exspression, parameters.ToArray()); //filter collection on the expression

if (sort != null) //do sorting
{
objectsList = query.OrderBy(“it.” + sort).ToList();
if (dir == “DESC”) objectsList.Reverse();
}
else
{
objectsList = query.ToList();
}

if (intStart + intLimit > objectsList.Count)
intLimit = objectsList.Count – intStart; //make sure the range we select is valid
objectsList = objectsList.GetRange(intStart, intLimit);
return objectsList;
}

#region Nested type: Filter

public class Filter
{
public string Datacomparison { get; set; }
public string DataType { get; set; }
public string DataValue { get; set; }
public string Field { get; set; }

public int Id { get; set; }

public static bool checkExistence(int filterIndex, NameValueCollection @params)
{
return (@params[string.Format(“filter[{0}][field]”, filterIndex)] != null);
}

public Filter(int id, HttpRequestBase request)
{
Id = id;
Field = request.Params[string.Format(“filter[{0}][field]”, id)];
DataType = request.Params[string.Format(“filter[{0}][data][type]”, id)];
DataValue = request.Params[string.Format(“filter[{0}][data][value]”, id)];
Datacomparison = request.Params[string.Format(“filter[{0}][data][comparison]”, id)];
}

public FilterExpressionResult getExpression()
{
string expressionString = null;
var expressionParams = new List(); //paramerters collection
switch (DataType)
{
case “string”:
expressionString = string.Format(“(it.{0} like ‘{1}%’)”, Field, DataValue);
break;
case “boolean”:
expressionString = string.Format(“(it.{0} = {1})”, Field, (DataValue == “true”) ? 1 : 0);
break;
case “numeric”:
switch (Datacomparison)
{
case “gt”:
Datacomparison = “>”;
break;
case “lt”:
Datacomparison = “”;
break;
case “lt”:
Datacomparison = “<"; break; default: Datacomparison = "="; break; } expressionParams.Add(new ObjectParameter("Param" + Id, DateTime.Parse(DataValue))); expressionString = string.Format("(it.{0} {2} {1})", Field, "@" + "Param" + Id, Datacomparison); break; case "list": var split = DataValue.Split(new[] { ',' }); var r = new string[split.Length]; for (var i = 0; i < split.Length; i++) { r[i] = string.Format("(it.{0} = '{1}')", Field, split[i]); } expressionString = string.Format("({0})", string.Join("OR", r)); break; } return expressionString != null ? new FilterExpressionResult { Expression = expressionString, Parameters = expressionParams } : null; } #region Nested type: FilterExpressionResult public class FilterExpressionResult { public string Expression { get; set; } public List Parameters { get; set; } } #endregion } #endregion } [/sourcecode] ah! that's it for now. i might post some helpers that can be used in your views when you want to render the grid. the advantage of using this would be, so you won't need to repeat all that javascript code in each and every view that you want to display a grid in. hope this will be helpful to someone. cheers!

Blog at WordPress.com.