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

1 comment: