tags:

views:

288

answers:

2

Apparently the db4o website was recently redone, and now old urls are giving 404 errors. Everytime I think I've found the answer, I get a 404 error.

I have a simple db4o database I've setup to store people.

public class Person
{
     public string Firstname { get; set;}
     public string Lastname {get;set;}
}

I've been able to run Linq queries on the database, and everything works wonderfully. I'm programming in a web environment, so I will need someone to identify and fetch unique objects from the database, so I simply configured the database to use UUID's. Now the problem has become, how can I get to the UUID information from the objects I get from the Linq query?

For example, let's say I get all the people stored in the database, and I need to generate the unique URL's for each person. I will use the UUID to do so. So I'll run this:

var people = (from Person p in db select p).ToList();

And then I'll iterate through the list

foreach( Person person in people)
{
  DoSomething(person);
}

The best solution would be making the UUID a property on the Person class, so that I could just:

var uuid = person.UUID;

I don't see a mechanism for doing that however. Am I missing something?

+4  A: 

I've answered this already here but together with other question. Therefore I answer it again: In db4o you have normally no id. db4o uses the object-identity to distinguish the object apart. So the same object in memory is going to be the same object for the database.

As long a you don't serialize object this works fine, you don't need any ID. However as soon as objects are serialized / disconnected this doesn't work anymore (Typical for web-apps).

I think this three options are possible:

  • Use the db4o internal id. You can get this id with IObjectContainer.Ext().GetID(object). And of course you can get a object by id: IObjectContainer.Ext().GetByID(id). However this id isn't forever. Defragmenting the database changes this id.
  • Using db4o's UUIDs. But db4o UUIDs are quite large
  • Creating ids by yourself. For example using a GUID. Or using a clever id-generator. Remember to index such a id-field when you use it in queries.

Of course you can create a base-class which provides the id-property with any of the implementations above.

Gamlor
Thanks, but I think you missed the point. I had already decided to go with UUID's, but unfortunately couldn't figure out a way to find the UUID after getting the object from the Linq query. The documentation I had found were using a different type of query to get the UUID. I used db.Ext().GetObjectInfo(person).GetUUID();That worked, but like you pointed out, the UUID is way to big to be practical here. I guess I'm going to have to bite the bullet and implement the hilo algorithm.
josh
Oh sorry. Yes you can get the db4o-uuid by 'db.Ext().GetObjectInfo(object).GetUUID()' and get to object by 'db.Ext().GetByUUID()'. It doesn't depend on the query-type.
Gamlor
Yeah, I should have focused more on the sentence "For example using a GUID." in your original post.
josh
A: 

Okay, here's what I've prototyped quickly, and it seems to be working. First, I created a base class for all my data objects. Right now, all it has is an int Id field, though I will probably use it for some other things as well.

Then I created an extension method on IObjectContainer.

public static class db4oExtensions
{
    public static void StoreWithId(this Db4objects.Db4o.IObjectContainer db, DataObject dao)
    {
        int count = (from DataObject datao in db select datao.Id).Max();
        dao.Id = count + 1;
        db.Store(dao);
    }
}

So now when I store an object in the db, I'll just call StoreWithId instead of Store. A few tests seem to show this is working. Now one problem I see is if I delete the object with the max value, I'll have two objects with identical id's, but which both don't exist at the same time. I'll figure out the answer to that later, possibly by just storing an int incrementer in the database itself that's only ever accessed through StoreWithId.

josh
Actually, I just realized that using .NET guid's may be a better solution, converting to a string first to avoid any box / unboxing issues.
josh
Upon further consideration, I've seen what was obvious: going with guid's for my objects would have avoided all of this trouble to begin with.
josh
btw. Since db4o 7.12 Guids should be handled correctly by db4o. Without strange boxing/unboxing issues.
Gamlor