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.

Archive