Saturday, March 28, 2009

LINQ: more like "Luckily I Never Quit"

I've been using LINQ quite a bit lately. As the blog title says: luckily, I never quit.

There are a lot of things to get used to with LINQ. For one, it uses deferred queries. When you make a change, you must submit changes before the change is reflected in the database. Yes, this mirrors the actions when working directly with a database (COMMIT), but when you're thinking of it as application logic, it seems counter-intuitive.

<aside>

At school, I'm in a class called INFO 465: Projects in Information Systems. The class is slow-going. At VCU, there are three tracks of studies in Information Systems: Application Development, Business Analysis, and Network Administration. Unfortunately, most of the people in BA and Networking are there because they don't want to do any programming at all. You would think a class geared to using your course skills would accommodate each track equally?

That's not the case in this class. There are two projects. One is individual work and the other is group work. The individual project is really just a large programming assignment to create an "Enterprise System" for a landscaping company. Luckily, the company consists of the landscaper, a truck, and his helper.

Anyway, to get back on track, we're allowed to do our project any way we want. Most of the people in the class chose to do Windows Forms using VB.NET examples provided by the teacher. Good luck with that! I chose to use ASP.NET, AJAX, Web Services, and LINQ. I chose this route because I wanted this class to be a learning experience, not just a copy-paste session for 3 hours a week.

</aside>

Back to LINQ. To be quick about development, I've decided to use GridViews, DetailsViews, and LinqDataSources. Every time I try to link a LinqDataSource to a GridView's selected key, I get this message:

Operator '==' incompatible with operand types 'Int32' and 'Object'

Here is an example of the LinqDataSource that throws this error:

<asp:LinqDataSource ID="srcSelectedOrder" runat="server" 
        ContextTypeName="INFO465_First_Web.DatabaseMaps.OrdersDataContext" 
        EnableDelete="True" EnableInsert="True" EnableUpdate="True" TableName="Orders" 
        Where="Id == @Id">
        <WhereParameters>
            <asp:ControlParameter ControlID="GridView1" Name="Id" 
                PropertyName="SelectedValue" Type="Int32" />
        </WhereParameters>
    </asp:LinqDataSource>
The problem is where you have the Where clause "Id == @Id". For some reason, the data source thinks @Id is an object instead of an Int32, even though Type="Int32" in the WhereParameters.

The fix is the change this to Where="Id == Int32?(@Id)". I don't know why this is. I mean, if you're taking a primary key as the DataKeyName, it is being passed as Int32 in the WhereParameters, why do you have to cast it? Maybe the LinqDataSource automatically converts Id == @Id to an SQL query that would look like "Id == '2'", and you have to cast to Int32 explicitly so it will look like "Id == 2" in the query? Again, this is another place that LINQ just seems backwards.

Here is the fixed data source:

<asp:LinqDataSource ID="srcSelectedOrder" runat="server" 
        ContextTypeName="INFO465_First_Web.DatabaseMaps.OrdersDataContext" 
        EnableDelete="True" EnableInsert="True" EnableUpdate="True" TableName="Orders" 
        Where="Id == Int32?(@Id)">
        <WhereParameters>
            <asp:ControlParameter ControlID="GridView1" Name="Id" 
                PropertyName="SelectedValue" Type="Int32" />
        </WhereParameters>
    </asp:LinqDataSource>

(I always format my code with http://www.manoli.net/csharpformat/)

Thursday, March 19, 2009

C++ Templated QuickSort Algorithm

It has been over a month since I posted. I've been really busy with all of my classes. So, instead of going too in depth with anything, I'm just going to share some code we've written. This is a QuickSort Algorithm that we adapted from the MIT Intro to Algorithms book. We just finished it last night (less than 12 hours ago), so it's not fully tested.
   1:  #ifndef _QUICKSORT_H
   2:  #define _QUICKSORT_H
   3:   
   4:  #include <vector>
   5:   
   6:  using namespace std;
   7:   
   8:  namespace QuickSort
   9:  {
  10:      
  11:  /* 
  12:      QuickSort Algorithm using Templates
  13:  
  14:      Algorithm was adapted from:
  15:          Introduction to Algorithms
  16:          By Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein
  17:          Contributor Thomas H. Cormen
  18:          Edition: 2, illustrated
  19:          Published by MIT Press, 2001
  20:          ISBN 0262032937, 9780262032933
  21:          1180 pages
  22:      Accessed March 2009
  23:      via http://books.google.com/books?id=NLngYyWFl_YC
  24:      See pages 145-147
  25:  
  26:  */
  27:      template<class T>
  28:      class QuickSort
  29:      {
  30:      public:
  31:          vector<T> *sortingArray;
  32:          int left;
  33:          int right;
  34:   
  35:          // Constructors
  36:          QuickSort();
  37:          QuickSort(vector<T> *sortArray);
  38:          QuickSort(vector<T> *sortArray, int startIndex, int endIndex);
  39:   
  40:          /**********************************************************************
  41:          * Partition and Swap Functions
  42:          **********************************************************************/
  43:          int Partition(vector<T> *sortArray, int startIndex, int endIndex);
  44:          void Swap(int l, int k);
  45:   
  46:      };
  47:   
  48:      template<class T>
  49:      QuickSort<T>::QuickSort()
  50:      {
  51:          sortingArray = new vector<T>();
  52:          left = 0;
  53:          right = 0;
  54:      }
  55:   
  56:      template<class T>
  57:      QuickSort<T>::QuickSort(vector<T> *sortArray)
  58:      {
  59:          int startIndex = 0;
  60:          int endIndex = 0;
  61:   
  62:          endIndex = (int)(*sortArray).size() - 1;
  63:   
  64:          QuickSort(sortArray, startIndex, endIndex);
  65:      }
  66:   
  67:      template<class T>
  68:      QuickSort<T>::QuickSort(vector<T> *sortArray, int startIndex, int endIndex)
  69:      {
  70:          if(startIndex >= endIndex)
  71:          {
  72:              return;
  73:          }
  74:   
  75:          // *initialize* the array
  76:          sortingArray = sortArray;
  77:   
  78:          // For instance: 1..n
  79:          left = startIndex;
  80:          right = endIndex;
  81:   
  82:          if(left < right)
  83:          {
  84:              // get pivot
  85:              int pivot = Partition(sortingArray, left, right);
  86:   
  87:              // sort left side
  88:              QuickSort(sortingArray, left, (pivot-1));
  89:   
  90:              // sort right side
  91:              QuickSort(sortingArray, (pivot+1), right);
  92:          }
  93:      }
  94:   
  95:      template<class T>
  96:      int QuickSort<T>::Partition(vector<T> *sortArray, int startIndex, int endIndex)
  97:      {        
  98:          // initially this start - 1 when startIndex is 0.
  99:          int l = startIndex - 1;
 100:          int k = endIndex;
 101:   
 102:          for(int i = startIndex; i <= k - 1; i++)
 103:          {
 104:              // Go until you find a value smaller than the last value.
 105:              if((*sortArray)[i] <= (*sortArray)[k])
 106:              {
 107:                  // increment l
 108:                  l++;
 109:   
 110:                  // swap i and j
 111:                  // NOTE: this is supposed to swap j with itself the first time.
 112:                  Swap(l, i);        
 113:              }
 114:          }    
 115:          
 116:          // when loop is finished, swap 
 117:          Swap(l + 1, k);
 118:   
 119:          return l + 1;
 120:      }
 121:   
 122:      template<class T>
 123:      void QuickSort<T>::Swap(int l, int k)
 124:      {
 125:          // create temp variable
 126:          T tmp;
 127:          
 128:          // store first element in temp
 129:          tmp =(*sortingArray)[l];
 130:   
 131:          // swap second element to first element
 132:          (*sortingArray)[l] = (*sortingArray)[k];
 133:   
 134:          // put temp variable in second element
 135:          (*sortingArray)[k] = tmp;
 136:      }
 137:   
 138:  }
 139:   
 140:  #endif

Archive