Thursday, April 30, 2009

Useful Serialization Methods of LINQ to SQL objects

I am just going through a project for my senior "Projects in Information Systems" class, commenting most of the complex logic.  I came across these two methods I wrote to serialze LINQ to SQL objects.  They came in pretty handy, so I thought I'd share even though they don't have error-handling.  I'm not too embarrassed. 
The way I used them was pretty ghetto, I was having troubles getting the objects I needed to serialize to be used in a Session object (I thnk it had something to do with an Order_Details table having two foreign keys to the same table, Ledger, for an IN and OUT field).  Anyway, I serialed the object to XML and just stored the whole string into a listBox's value.  I know that's begging for poor performance, and overriding the data validation checks is opening the ASP.NET page up for security issues, but the only people who are going to use this are me and my instructor.  So, it was a quick work around. I could have stored it in a Session Object as a string, but then I would have had to call some funky work around for the listBox.  Anyway, enough about that.
   1:   
   2:          /// <summary>
   3:          /// Serializes a LINQ object to an XML string
   4:          /// </summary>
   5:          /// <typeparam name="T">Type of the Object</typeparam>
   6:          /// <param name="linqObject">The LINQ object to convert</param>
   7:          /// <returns>string</returns>
   8:          public static string SerializeLINQtoXML<T>(T linqObject)
   9:          {
  10:              // see http://msdn.microsoft.com/en-us/library/bb546184.aspx
  11:              DataContractSerializer dcs = new DataContractSerializer(linqObject.GetType());
  12:   
  13:              StringBuilder sb = new StringBuilder();
  14:              XmlWriter writer = XmlWriter.Create(sb);
  15:              dcs.WriteObject(writer, linqObject);
  16:              writer.Close();
  17:   
  18:              return sb.ToString();
  19:          }
  20:   
  21:          /// <summary>
  22:          /// Deserializes an XML string to a LINQ object
  23:          /// </summary>
  24:          /// <typeparam name="T">The type of the LINQ Object</typeparam>
  25:          /// <param name="input">XML input</param>
  26:          /// <returns>Type of the LINQ Object</returns>
  27:          public static T DeserializeLINQfromXML<T>(string input)
  28:          {
  29:              DataContractSerializer dcs = new DataContractSerializer(typeof(T));
  30:   
  31:              TextReader treader = new StringReader(input);
  32:              XmlReader reader = XmlReader.Create(treader);
  33:              T linqObject = (T)dcs.ReadObject(reader, true);
  34:              reader.Close();
  35:   
  36:              return linqObject;
  37:          }
  38:   

Saturday, April 25, 2009

Storing Generics in ASP.NET Profile object

Sometimes, I'll come across a problem that I research for an hour or two. When I find the solution, I think "Wow, that should have been the first thing I tried!"
This is one of those occasions. 

I decided to use the ASP.NET profile instead of Session objects to store a list of products.  So, in web.config, I tried a number of "work-arounds" that I found online, including:

   1:  <profile>
   2:  ...
   3:        <properties>
   4:          <add name="RecentlyViewed" allowAnonymous="false" type="System.Collections.Generic.List`1[Model.Product]" serializeAs="Xml"/>
   5:        </properties>
   6:  </profile>


The problem I was having, and it seems a lot of people are having, is that System.Collections.Generic.List`1[Model.Product] throws an error. For some people, it seems to work. Well, I tried changing the lt and gt in the generic list so the XML would parse it as it is written in the code-behind. That didnt work.

The solution: Create a class which inherits from List<Model.Product>

For instance:

   1:  using System;
   2:  using System.Collections.Generic;
   3:   
   4:  namespace Model
   5:  {
   6:      /// <summary>
   7:      /// This class wraps the Generic List into a class to serialize in Profile provider
   8:      /// </summary>
   9:      [Serializable]
  10:      public class RecentlyViewed : List<Model.Product>
  11:      {
  12:          public RecentlyViewed()
  13:          {
  14:          }
  15:      }
  16:  }

This works beautifully! Now, in web.config, you can do the following:

   1:  <profile>
   2:  ...
   3:        <properties>
   4:          <add name="RecentlyViewed" allowAnonymous="false" type="Model.RecentlyViewed" serializeAs="Xml"/>
   5:        </properties>
   6:  </profile>

Tuesday, April 14, 2009

Displaying multiple fields in a Dropdownlist's DataTextField

I've encountered this problem on occasion, where I want to display more than one field in a dropdownlist's DataTextField property.  In the past, I've overcome this problem by rewriting a SQL statement, or adding another column in the database itself to accomodate my needs.

In one of my classes (INFO 465: Projects in Information Systems @ VCU), we're working from a database which we're not allowed to change.  The reason we can't change it is because the instructor uses the same database for his examples.  I could just write another method into my business logic layer, but it would get cluttered pretty quickly.
So, I decided to make use of LINQ and found the following solution:

   1:  ddlUsers.DataSource = BLL.Employee.GetEmployees()
   2:                  .Select(be => 
   3:                      new { 
   4:                          ID = be.Id, 
   5:                          FullName = String.Format("{0}{1}{2}", 
   6:                                      be.LastName,
   7:                                      (!string.IsNullOrEmpty(be.FirstName) ? ", " : string.Empty),
   8:                                      be.FirstName)
   9:                          }).AsEnumerable();


This takes the List of Business Entity objects and uses the LINQ select statement to generate an implicit/anonymous object from that. The only downfall to this method is that the new object only has local scope. But, since I'm only using this in a dropdown, it's a pretty nifty trick.

Wednesday, April 1, 2009

T-SQL Multi-Table Delete

I was trying to run a DELETE query on multiple tables and I kept getting this error: The DELETE statement conflicted with the REFERENCE constraint
I'm not that great with SQL, but I can get by.  DELETEs have always been somethng that have given me trouble.  So, I thought I'd share this simple fix.
DELETE FROM PRODUCT
FROM BOOK
WHERE BOOK.ID = PRODUCT.BOOK_ID
AND BOOK.ID = @BOOK_ID


You just have to make sure you put the table with the FK as the first table in the query.
I guess I should have paid a little more attention in Database class.  We learned Oracle, which is different from Microsoft's SQL in many ways.

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

Monday, February 2, 2009

My beginnings in C++

This semester (my final semester at VCU), I am taking INFO 450: Advanced Programming, which concentrates in C++. We're learning both native and managed C++. Our first assignment was simple: a console application to calculate the monthly payments on a car loan, based on interest rate, total loan, and loan duration. That was pretty easy.

This assignment was pretty rough. We had to code a fully functional ATM application, which uses a hardcoded bank database, accounts, authentication, withdrawal & deposit simulation, etc. We were told that we could mirror the ATM case study at the end of our Learn to Program C# 2005 by Deitel (the book from intermediate programming).

After mirroring the C# code, I kept getting error after error. It was ridiculous how every error stemmed from how header files were used in my code. Eventually, I worked out the problems with the header files. Then, I kept getting this compiler error: LNK2019. I searched and searched online, and couldn't find a suitable answer. Finally, I retraced all my code, and realized that I had three classes (Withdrawal, Deposit, BalanceInquiry) all overriding the virtual function 'Execute' from class Transaction, but that class wasn't marked virtual. This probably should have been the first place I looked, but keep in mind we were given this assignment the day after we learned about references.

To make a long story short, I was receiving LNK2019 errors because of my virtual functions. The error was caused by declaring the function as "virtual void Execute();" instead of "virtual void Execute() = 0;" Embarrassingly, that little mistake took me forever to figure out. I somewhat hope that whatever path I take in the future uses tools with less cryptic error messages.

C# Insertion Sorting algorithm

Here is a console application to test an Insertion Sorting algorithm adapted from chapter 2 of MIT's Introduction to Algorithms. I thought this might come in handy for any beginners, as well as a fun way to test your computer's performance.
My desktop averages about 24.9 seconds, which, of course, depends on how scattered the integers are in the array.

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:   
   6:  namespace InsertionSorting
   7:  {
   8:      class Program
   9:      {
  10:          static void Main(string[] args)
  11:          {
  12:              // int[] A = {5, 2, 4, 6, 1, 3};
  13:              int initializer = 100000;
  14:              int[] A = new int[initializer];
  15:   
  16:              for (int c = 0; c < A.Length; c++)
  17:              {
  18:                  A[c] = c;
  19:              }
  20:   
  21:              // Random shuffle
  22:              Random rand = new Random();
  23:              for (int d = 0; d < A.Length; d++)
  24:              {
  25:                  int firstInt = A[d];
  26:                  int swapIndex = rand.Next(initializer);
  27:                  int secondInt = A[swapIndex];
  28:   
  29:                  A[d] = secondInt;
  30:                  A[swapIndex] = firstInt;
  31:              }
  32:              
  33:              //Console.Write("Array before sorting: ");
  34:              //foreach (int number in A)
  35:              //{
  36:              //    Console.Write("{0} ", number);
  37:              //}
  38:              //Console.WriteLine("");
  39:   
  40:              int key;
  41:              int i;
  42:              int j;
  43:   
  44:              Console.Write("Insertion Sorting array of {0} numbers, please wait...", initializer);
  45:              
  46:              DateTime start = DateTime.Now;
  47:              for (j = 1; j < A.Length; j++)
  48:              {
  49:                  key = A[j];
  50:                  i = j;
  51:   
  52:                  while (i > 0 && A[i - 1] > key)
  53:                  {                    
  54:                      A[i] = A[i-1];
  55:                      i--;
  56:                  };
  57:                  
  58:                  A[i] = key;
  59:              }
  60:              DateTime finish = DateTime.Now;
  61:              
  62:              //Console.Write("Array after sorting: ");
  63:              //foreach (int number in A)
  64:              //{
  65:              //    Console.Write("{0} ", number);
  66:              //}
  67:   
  68:              Console.WriteLine("");
  69:              Console.WriteLine("Duration: {0} seconds", (finish - start).ToString());
  70:          }
  71:      }
  72:  }
  73:   

Thursday, January 1, 2009

Silverlight 2.0, broken XAML Intellisense fix

I installed all the necessary files for Silverlight today. When I created a project, the xaml document didn't have intellisense and opened as a text instead of XML-based document. I tried a few fixes, one guy recommended right-clicking on the file and choosing "Open with.." and selected XML Editor as the default. This didn't work for me. I tried following Karen Meier's fix here. That didn't work either. Then, I figured I would try resetting Visual Studio. So, checking the documentation on devenv switches, specifically this one, I ran devenv /resetskippkgs and checked the intellisense. This fixed my XAML intellisense!

Archive