Вопрос
По-видимому, веб-сайт db4o был недавно переделан, и теперь старые URL-адреса выдают ошибки 404.Каждый раз, когда я думаю, что нашел ответ, я получаю сообщение об ошибке 404.
У меня есть простая база данных db4o, которую я настроил для хранения людей.
public class Person
{
public string Firstname { get; set;}
public string Lastname {get;set;}
}
Я смог запускать запросы Linq к базе данных, и все работает замечательно.Я программирую в веб-среде, поэтому мне понадобится кто-то для идентификации и извлечения уникальных объектов из базы данных, поэтому я просто настроил базу данных на использование UUID.Теперь проблема в том, как я могу получить информацию UUID из объектов, которые я получаю из запроса Linq?
Например, допустим, я получаю всех людей, хранящихся в базе данных, и мне нужно сгенерировать уникальный URL-адрес для каждого человека.Я буду использовать UUID для этого.Так что я займусь этим:
var people = (from Person p in db select p).ToList();
А затем я пройдусь по списку
foreach( Person person in people)
{
DoSomething(person);
}
Лучшим решением было бы сделать UUID свойством в классе Person, чтобы я мог просто:
var uuid = person.UUID;
Однако я не вижу механизма для этого.Я что-то упускаю?
Решение
Я уже отвечал на этот вопрос здесь но вместе с другим вопросом.Поэтому я отвечаю на это еще раз:В db4o у вас обычно нет идентификатора.db4o использует объект-идентичность чтобы отличать объект друг от друга.Таким образом, один и тот же объект в памяти будет одним и тем же объектом для базы данных.
Пока вы не сериализуете объект, это работает нормально, вам не нужен никакой идентификатор.Однако, как только объекты сериализуются / отключаются, это больше не работает (типично для веб-приложений).
Я думаю, что возможны эти три варианта:
- Используйте db4o внутренний идентификатор.Вы можете получить этот идентификатор с помощью
IObjectContainer.Ext().GetID(object)
.И, конечно, вы можете получить объект по идентификатору:IObjectContainer.Ext().GetByID(id)
.Однако этот идентификатор не вечен.Дефрагментация базы данных изменяет этот идентификатор. - Использование db4o UUIDs ( идентификаторы пользователя ).Но UUID-файлы db4o довольно большие
- Создание идентификаторов самостоятельно.Например, используя GUID.Или использование умного генератора идентификаторов.Не забудьте проиндексировать такое поле идентификатора, когда вы используйте его в запросах.
Конечно, вы можете создать базовый класс, который предоставляет id-свойство с любой из описанных выше реализаций.
Другие советы
Итак, вот что я быстро создал прототип, и, похоже, это работает.Во-первых, я создал базовый класс для всех моих объектов данных.Прямо сейчас все, что в нем есть, - это поле int Id, хотя я, вероятно, буду использовать его и для некоторых других целей.
Затем я создал метод расширения в 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);
}
}
Так что теперь, когда я сохраняю объект в базе данных, я просто вызываю StoreWithId вместо Store .Несколько тестов, кажется, показывают, что это работает.Теперь одна проблема, которую я вижу, заключается в том, что если я удалю объект с максимальным значением, у меня будут два объекта с одинаковыми идентификаторами, но которые оба не существуют одновременно.Я выясню ответ на это позже, возможно, просто сохранив int incrementer в самой базе данных, доступ к которой возможен только через StoreWithId .