Castle Demo AppGetting Started With Active Record

time to read 17 min | 3366 words

A few words about Active Record: Active Record is a wrapper around NHibernate, which is an Object Relational Mapping for .Net. I'm not going to explain how things works in this post, just how to use them. If you're going to be a serious Active Record user, I'm strongly recommend that you'll learn how to use NHibernate. You'll appriciate how much Active Record does for you much more afterward.

Setting The Environment:

Assuming that you already have the Castle's binaries on your machine, let's start by creating a class library project named "MythicalBugTracker.Model" in Visual Studio, I put my in "F:\MythicalBugTracker"

Add the following reference:

  • Castle.ActiveRecord.dll
  • NHibernate.dll

Let's create our User class, we will start with this code:

[ActiveRecord("Users")]

public class User : ActiveRecordBase<User>{

Notice that we created an Active Record class (by specifying the [ActiveRecord] attribute, and that it is pointed to the Users table. We also inherit from ActiveRecordBase<T>, which gives us all the Save/Find/Delete methods without any extra coding. Now let's consider what properties a user has, it propbably need a name and email, a password is probably needed as well. Since we will be saving the user to database, we'll need some sort of a unique id as well. We could use the user name or the email, but I like to use artifical keys when possible, so it's will be a user id.

    string _name, _email, _password;

    int _id;

So far, nothing out of the ordinary, now let's see the properties. We'll start with the Id property:

    [PrimaryKey(PrimaryKeyType.Identity,

       Access = PropertyAccess.NosetterCamelcaseUnderscore)]

    public int Id

    {

        get { return _id; }

    }

There is a couple of interesting things here, first, we are using the [PrimaryKey] attirubte to specify that this is the primary key of the class and we specify the type as an identity column. Notice that I did not define a setter for this property. The reasoning behind that is that the only thing that should set the Id is the databsae, and there is no point in letting an outsider access to change the user id. The Access property on the attribute tells ActiveRecord to write to the field directly when it needs to set it (usually after loading it from the database or creating a user) instead of using the property setter, it's default behaviour.

Now let's define the rest of the properties:

    [Property]

    public string Email

    {

        get { return _email; }

        set { _email = value; }

    }

 

    [Property]

    public string Name

    {

        get { return _name; }

        set { _name = value; }

    }

As you can see, the Email and Name properties are fairly normal, they are just decorated with a [Property] attribute, which tells Active Record that this property should be persisted to database.

    [Property(Access=PropertyAccess.FieldCamelcaseUnderscore)]

    public string Password

    {

        set { _password = Hash(value); }

    }

The Password property is an interesting one, it doesn't have a getter. Again, this is me thinking that there isn't really any point in getting the user's password, the only use for that is to query the user from the database. Again, we use the Access property on the attribute to specify that Active Record should go directly to the field, notice that this time we specified Field access, and not the NoSetter access. The Hash() method is a static method that simply return the MD5 hash of the values you give it.

Now we need a way to find a user. ActiveRecordBase<T> already provides a good way to do that, but only by the user id, I want to be able to find a user by its name and password. Here is how it is done:

    public static User FindUserByLogin(string name, string password)

    {

        string hashedPassword = Hash(password);

        return FindOne(Expression.Eq("Name", name),

            Expression.Eq("Password", hashedPassword));

    }

We get the password as plain text, hash it and then use the FindOne method (which will return a single result or null) to pass the query the database. In this case, we ask for a user with the specified name and password.

Okay, so now we have the User class, it's time to think about persisting it. The path of least resistance in .Net 2.0 is to use SQL Express Database File, so we'll go with that one.

Using Visual Studio.Net, I created a database file in "F:\MythicalBugTracker\Data\MythicalBugTracker.mdf". And then created the following table:

CREATE TABLE [dbo].[Users](

      [Id] [int] IDENTITY(1,1) NOT NULL,

      [Name] [nvarchar](50) NOT NULL,

      [Email] [nvarchar](50) NOT NULL,

      [Password] [char](24) NOT NULL,

 CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED

(

      [Id] ASC

)

That is it, in this point, I've a fully functional User class. The next step is to create projects.

More posts in "Castle Demo App" series:

  1. (03 Mar 2006) ViewComponents, Security, Filters and Friends
  2. (01 Mar 2006) Code Update
  3. (01 Mar 2006) Queries and Foreign Keys
  4. (28 Feb 2006) Complex Interactions
  5. (25 Feb 2006) CRUD Operations on Projects
  6. (22 Feb 2006) Let There Be A New User
  7. (22 Feb 2006) Updating our Users
  8. (20 Feb 2006) Getting serious, the first real page
  9. (20 Feb 2006) MonoRail At A Glance
  10. (20 Feb 2006) The First MonoRail Page
  11. (19 Feb 2006) Many To Many Relations
  12. (19 Feb 2006) Lazy Loading and Scopes
  13. (17 Feb 2006) Active Record Relations
  14. (17 Feb 2006) Getting Started With Active Record