Thursday, May 27, 2010

Starting up RavenDB with .NET 3.5

The application I’m writing isn’t in a very far stadium yet, but I do have some implementation of repositories using NHibernate. Now I want to switch to RavenDB.

So I downloaded RavenDB (the latest build at this time – build 81) and unzipped it. I wanted to follow the RavenDB Hello World tutorial, but soon found out its built for .NET 4.

I don’t have .NET 4 or Visual Studio 2010 yet, but luckily there’s a client for .NET 3.5. I removed all NHibernate references and added one to Raven.Client-3.5.dll in m Dal project.

You’re sort of screwed if you only have Visual Studio 2008 and .NET 3.5 installed. I wanted to use it as an embedded client, but that’s .NET 4.0 only at the moment.

So I started up the server (check the RavenDB Hello World for more info) and surfed to http://localhost:8080 and all looks well.

On of the first things I did, was change the type of the Id properties of my domain objects from a Guid to a string (which was a good moment to introduce a BaseEntity of which other classes can derive). According to the RavenDB Hello World, this is configurable, but I can’t be bothered right now to find out.

I have a BaseRepository that implements the following interface:

public interface IBaseRepository<T>

    T GetOneById(Guid id);
    IList<T> GetAll();
    void SaveOrUpdate(T aggregate);
    void Delete(T aggregate);
}

Other repositories inherit from the BaseRepository, and, through their interface, only expose their relevant methods:

public class PatientRepository : BaseRepository<Patient>, IPatientRepository
{
    public PatientRepository(string connectionStringName) : base(connectionStringName)
    {
    }
}

Let’s start with the GetAll method. This is the NHibernate way:

public IList<T> GetAll()
{
    ICriteria criteria = Session.CreateCriteria(typeof (T));
    return criteria.List<T>();
}

In the constructor of my BaseRepository, I create an IDocumentStore (an expensive thing to do):

_store = new DocumentStore { Url = @"D:\data" };
_store.Initialise();

Then my method creates a session (a cheap thing to do):

public IList<T> GetAll()
{
    using (var session = _store.OpenSession())
    {
        return session.LuceneQuery<T>().ToList();
    }
}

I put all my other methods in comment, and everything builds and the application works!

I am using the LuceneQuery because the normal Query() method needs an index, which I don’t have yet. I’m still researching how to do this in the best way.

There’s the DocumentStore.DatabaseCommands.PutIndex method (I found a good example on Rob Ashtons blog), but that would execute everytime my application runs. Or you can check out the RavenDB documentation on indexes, but that seems overly complicated.

Next post should be something on switching from NHibernate to RavenDB, but now it’s time for my couch.

Thursday, May 20, 2010

Data storage for a stand-alone client application

I’m developing a stand-alone client application that will be able to store a fair amount of data. No client-server stuff, just plain old open-the-application-change-the-data-save-close. I need a good way to store the data and, traditionally, developers look at SQL databases for data storage. But I’m thinking this will make it overly complex. A search for alternatives starts.

The application is for the administration of a speech therapist. It should have the patients, appointments, documents, etc. But also more complex business logic such as calculating payments for patients (which in Belgian social security can be complex), calculating how many more session (appointments) a patient can have (which can be, but isn’t always, legally regulated), etc. So just an Excel file or an Access database won’t do. And besides, I’m a .NET developer.

So you’d take a SQL database right? With the compact edition, no? And, being all up-to-date on our developing skills, use NHibernate! Well, I’ve been reading the No SQL posts by Ayende with much interest (and some other blogs too), and it hit me that the whole SQL and mapping files thing is quite complex.

I know there a lot of info out there on how to use NHibernate, but I must say, it stays kind of hard to do it right. You always get into trouble using collections, you have to make compromises in your domain, there’s all sorts of best ways to manage your sessions, etc. Being a developer, and not a database specialist, I won’t to write code, instead of having to hassle with data storage details.

Why not go old school, and save your objects to file (binary or xml)? I could do that, but I don’t have any experience with doing this on a lot of objects, objects that hold other objects, I don’t know how this affects performance, …

So I did start looking for object databases or document databases. db4o looked promising and I must look into it further. I first discarded it as an option due to licensing (I might go commercial with my application if all goes well). I checked other options like the most known ones: MongoDB, CouchDB, but they seemed quite complex also, in part because they’re not targeting the .NET platform.

So I ended up choosing RavenDB, which has a paying license for commercial applications also, like db4o. But I haven’t gone into the details of the licensing yet, so I couldn’t tell you the difference. Maybe I didn’t give db4o a decent chance, but I’m going to try RavenDB now anyway.