db4o, Linq, and UUID's

2019-04-14 05:45发布

问题:

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?

回答1:

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.



回答2:

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.



标签: linq uuid db4o