SyntaxHighlighter

Wednesday, February 11, 2009

Object Databases in .NET

I'm probably going to get a lot of push back on this... especially from DB guys I know( Douglas, Thom, Glenn, you know who you are). :-)
Anyway, I've recently discovered db4.0... this is a really good object database implementation.
So good... that is supports T-SQL and LINQ. It's file based but the speed is impressive. Now... I'm not saying that this is finally the end of databases, but it's a good start for any small apps like mine that don't need the overhead of a powerful db platform like SQL/Oracle. I think it's wise to use a technology like this for small persistence scenarios... for instance, in my day job I deal with lots of calculations, estimating, etc. Quite a few of the calculations are calculated on the fly which initially takes a while depending on the state that the user left the application. So instead of dismissing persistence in this scenario and paying the cost for calculating rows and rows of data, I can store it all in a light weight, 1 .dll, 1 file, database of calculated values.


Below is an attempt to give you a better idea with out having to download the free stuff. :-)

using System;
using System.IO;

using Db4objects.Db4o.Query;
using Db4objects.Db4o.Tutorial;

namespace Db40Examples
{
public class Example1
{
public static void Main(string[] args)
{
IObjectContainer db = Db4oFactory.OpenFile("Path to filename here");
try
{
StoreFirstPilot(db); //create
StoreSecondPilot(db); //create
RetrieveAllPilots(db); //read
RetrievePilotByName(db); //read
RetrievePilotByExactPoints(db); //read
UpdatePilot(db); //update
DeleteFirstPilotByName(db); //delete
DeleteSecondPilotByName(db); //delete

}
finally
{
db.Close();
}
}

public static void AccessDb4o()
{
IObjectContainer db = Db4oFactory.OpenFile("Path to filename here");
try
{
// do something with db4o
}
finally
{
db.Close();
}
}

public static void StoreFirstPilot(IObjectContainer db)
{
Pilot pilot1 = new Pilot("Michael Schumacher", 100);
db.Store(pilot1);
Console.WriteLine("Stored {0}", pilot1);
}

public static void StoreSecondPilot(IObjectContainer db)
{
Pilot pilot2 = new Pilot("Rubens Barrichello", 99);
db.Store(pilot2);
Console.WriteLine("Stored {0}", pilot2);
}

public static void RetrieveAllPilotQBE(IObjectContainer db)
{
Pilot proto = new Pilot(null, 0);
IObjectSet result = db.QueryByExample(proto);
ListResult(result);
}

public static void RetrieveAllPilots(IObjectContainer db)
{
IObjectSet result = db.QueryByExample(typeof(Pilot));
ListResult(result);
}

public static void RetrievePilotByName(IObjectContainer db)
{
Pilot proto = new Pilot("Michael Schumacher", 0);
IObjectSet result = db.QueryByExample(proto);
ListResult(result);
}

public static void RetrievePilotByExactPoints(IObjectContainer db)
{
Pilot proto = new Pilot(null, 100);
IObjectSet result = db.QueryByExample(proto);
ListResult(result);
}

public static void UpdatePilot(IObjectContainer db)
{
IObjectSet result = db.QueryByExample(new Pilot("Michael Schumacher", 0));
Pilot found = (Pilot)result.Next();
found.AddPoints(11);
db.Store(found);
Console.WriteLine("Added 11 points for {0}", found);
RetrieveAllPilots(db);
}

public static void DeleteFirstPilotByName(IObjectContainer db)
{
IObjectSet result = db.QueryByExample(new Pilot("Michael Schumacher", 0));
Pilot found = (Pilot)result.Next();
db.Delete(found);
Console.WriteLine("Deleted {0}", found);
RetrieveAllPilots(db);
}

public static void DeleteSecondPilotByName(IObjectContainer db)
{
IObjectSet result = db.QueryByExample(new Pilot("Rubens Barrichello", 0));
Pilot found = (Pilot)result.Next();
db.Delete(found);
Console.WriteLine("Deleted {0}", found);
RetrieveAllPilots(db);
}

Of course no example would be complete with out LINQ....


public static void StoreObjects(IObjectContainer db)
{
db.Store(new Car("Ferrari", (new Pilot("Michael Schumacher", 100))));
db.Store(new Car("BMW", (new Pilot("Rubens Barrichello", 99))));
}

public static void RetrievePilot(IObjectContainer db)
{
IEnumerable result = from Pilot p in db
where p.Name.StartsWith("Michael")
select p;
ListResult(result);
}

public static void RetrievePilotByCars(IObjectContainer db)
{
IEnumerable result = from Car c in db
where c.Model.StartsWith("F")
&& (c.Pilot.Points > 99 && c.Pilot.Points <150)
select c.Pilot;
ListResult(result);
}

public static void RetrievePilotUnoptimized(IObjectContainer db)
{
IEnumerable result = from Pilot p in db
where (p.Points - 81) == p.Name.Length
select p;
ListResult(result);
}



So far it's proven to be a quick way to get persistence up and going in my app with out all the worrying about "is my schema right?" kind of questions in my head. It's definitely going to be something I'll try to incorporate in to my unit tests in the future.

-Develop With Passion

Gearing up for Mix09

It's official!!! I'm heading to Mix09 in Las Vegas next month. Luckily, I was invited by a blue badger. Since this is my first Microsoft Conference ever (outside the road shows and free msdn events) I'm definitely going to live it up. Get swag, get some questions answered and come back to Seattle with some new tricks and better approaches. Since I've been heavily involved with Silverlight2 and WPF I've been getting the old designer/animator bug in me again. :-)
It's nice to break out my old 3D stuff and Flash stuff and refresh the skills enough to reuse them in a .net application. I honestly never thought I'd type that, but it's true. The latest application that I'm working on is for a High School in Eastern Washington(as I mentioned in a previous post). The app is entirely silverlight2 and c# and is heavy on the animation side. I wanted to build an IPhone like experience for the application. Since it needs to appeal to teenagers, I figure eye candy like that had to be done. So far it's working out(for the most part). I'm constantly second guessing myself on the transitions from one screen to the next. I want full control over this, so that I can ease in and out anyway I want. Thus far I've been using Nikhil code base as a guide, but I still think there should be a better way. So hopefully I'll learn something about that at mix.
Also... the backend story of the application is not traditional by any means. I'll speak more on this in a later post, but the concept of object databases (at least in my mind)has taken on a whole new meaning.

-Develop With Passion