How To: NHibernate Parent/Child Relationships

So you’re trying to setup a Parent/Child relationship using NHibernate. This is easy enough when you allow the foreign keys to be null in your database. Of course this is not desirable for data integrity so you disallow nulls. Now NHibernate is pissed because it wants to insert the child row first then update it with the parent id.

You can fix this by setting up a bi-directional relationship. Simply put, try the following.

In your Parent.hbm.xml add:

<set name="Children" inverse="true" cascade="all-delete-orphan">
 <key column="parent_id"/>
 <one-to-many class="Child"/>
</set>

In your Child.hbm.xml add:

<many-to-one name="Parent" column="parent_id" not-null="true"/>

Now you need to make sure you update the Child class to “know about” the Parent. To make this easy add this method to your Parent class:

public void AddChild(Child c)
{
 c.Parent = this;
 this.Add(c);
}

Now we can do this:

Parent p = new Parent();
Child c = new Child();
p.AddChild(c);
session.Flush();

That’s the tall and skinny of it. To really understand this concept check out Chapter 16 of the NHibernate Reference Documentation.

If Then Else Shorthand in C#

Sometimes you need to use “If Then Else” logic on something really simple, but all those brackets and parentheses are ugly and confusing. So instead use some fancy shorthand!

In this example I want to display the top 5 items in my array, but if my array is less than 5 items long I want to show all of the items up to the length of my array. (Otherwise I’d get an “index out of bounds” error for trying to access array items that don’t exist.)

int showTopEntries = 5;

showTopEntries = showTopEntries >= totalEntries ? totalEntries : showTopEntries;

This reads as: If 5 is greater than or equal to my array’s length, then use my array’s length, else use 5.

Your significant other is gonna’ be really impressed with this bit of code! Well, unless your significant other is also a programmer… then my sarcasm is lost. :/

Extend Visual Studio 2005 DataSet Designer Using Partial Classes

One of my favorite features of Visual Studio 2005 is the easy to use DataSet designer. If you haven’t tried using the DataSet designer to create your data access layer try it out. Brian Noyes has written a nice tutorial here.

However, one issue I have with the DataSet designer is that it doesn’t give you the ability to create a SqlDataReader from the design interface. Fortunately there is a way around this limitation. Using partial classes you can extend the DataSet designer’s built in functionality to add your own methods. Brian Noyes touches on this in his tutorial I referenced above.

I have a little cheat to share that makes adding a SqlDataReader method to your TableAdapter a snap.

First off, you need to use the designer to create a TableAdapter. Have it create a GetData method for you.

Next you need to create a new class file for your project. I recommend naming it something like ‘<the name of your DataSet xsd file>Custom.cs’. That way it’s easy to identify.

Now you need to extend the namespace of your DataSet, and create a partial class for the TableAdapter.

Here comes the cheat.

Highlight the name of your TableAdapter you just created a partial class for. Right-click on it, and click on “Go to Definition.” This will take you to the Microsoft generated code for your TableAdapter. Below the definition code you should be able to find the ‘GetData’ method. Copy that entire method block and retrofit it into the partial class you created for your SqlDataReader. Now simply replace the section of Microsoft generated code that creates and returns a DataTable with code that returns a SqlDataReader.

When you’re done you’ll end up with a class file that looks something like the following.

using System;
using System.Data;
using System.ComponentModel;
using System.Data.SqlClient;

namespace DataSetDirectTouchTableAdapters
{
    public partial class displayResponseQuestionTableAdapter : Component
    {

        public virtual SqlDataReader GetReader(System.Nullable ResponseSet, System.Nullable Question)
        {
            this.Adapter.SelectCommand = this.CommandCollection[0];
            if ((ResponseSet.HasValue == true))
            {
                this.Adapter.SelectCommand.Parameters[1].Value = ((int)(ResponseSet.Value));
            }
            else
            {
                this.Adapter.SelectCommand.Parameters[1].Value = System.DBNull.Value;
            }
            if ((Question.HasValue == true))
            {
                this.Adapter.SelectCommand.Parameters[2].Value = ((int)(Question.Value));
            }
            else
            {
                this.Adapter.SelectCommand.Parameters[2].Value = System.DBNull.Value;
            }
            this._connection.Open();
            return this.Adapter.SelectCommand.ExecuteReader(CommandBehavior.CloseConnection);
        }
    }
}

After you rebuild your project you can access the GetReader method via Intellisense! Good times. 🙂

Tutorial on how to open and read an email using C# and POP3

For a recent project I found a great tutorial on how to read and manipulate emails using POP3 on Developer Fusion.

Two things you should note when trying this code.

1) POP3 protocol won’t actually delete the email until you call the QUIT command. If your application fails before you call the Disconnect() method, no emails will be deleted.

2) I was unable to view the content of my emails without making a modification to the Response() method. Apparently the buffersize used in the tutorial was not sufficient for the emails I was viewing. The new method I used is posted on the tutorial’s feedback forum by “ddoctor.” It is as follows:

private string Response()
{
   System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();

   long buffersize = 1024;
   byte[] serverbuff = new byte[buffersize];
   NetworkStream stream = GetStream();
   int count = 0;
   while (true)
   {
      byte[] buff = new byte[2];
      int bytes = stream.Read(buff, 0, 1 );
      if (bytes == 1)
      {
         // if serverbuffer is full, double its capacity
         if (count == buffersize)
         {
            byte[] temp = new byte[buffersize * 2];

            int i = 0;
            while (i < buffersize)
            {
               temp = serverbuff;
               i++;
            }
            buffersize *= 2;
            serverbuff = temp;
         }

         serverbuff[count] = buff[0];
         count++;

         if (buff[0] == '\n')
         {
            break;
         }
      }
      else
      {
         break;
      };
   };
}