Можно ли открывать файл DB4o для запроса, вставки, обновления несколько раз? - PullRequest
2 голосов
/ 08 июня 2010

Вот как я думаю об использовании DB4o. Когда мне нужно сделать запрос, я бы открыл файл, прочитал и закрыл:

using (IObjectContainer db = Db4oFactory.OpenFile(Db4oFactory.NewConfiguration(), YapFileName))
{
    try
    {
        List<Pilot> pilots = db.Query<Pilot>().ToList<Pilot>();
    }
    finally
    {
       try { db.Close(); }
       catch (Exception) { };
    }
}

Через некоторое время, когда мне нужно вставить, тогда

using (IObjectContainer db = Db4oFactory.OpenFile(Db4oFactory.NewConfiguration(), YapFileName))
{
    try
    {
        Pilot pilot1 = new Pilot("Michael Schumacher", 100);
        db.Store(pilot1);
    }
    finally
    {
       try { db.Close(); }
       catch (Exception) { };
    }
}

Таким образом, я думал, что сохраню файл более аккуратным, открывая его только при необходимости и закрывая его большую часть времени. Но я продолжаю получать InvalidCastException

Unable to cast object of type 'Db4objects.Db4o.Reflect.Generic.GenericObject' to type 'Pilot'

Как правильно использовать DB4o?

Ответы [ 2 ]

5 голосов
/ 09 июня 2010

Нет, это не очень хорошая идея. db4o ObjectContainers предназначены для того, чтобы они оставались открытыми во время работы вашего приложения. Пара причин:

  • db4o поддерживает систему ссылок для идентификации постоянных объектов, поэтому он может выполнять обновления, когда вы вызываете #store () для объекта, который уже сохранен (вместо хранения новых объектов). Эта система ссылок закрывается при закрытии ObjectContainer, поэтому обновления не будут работать.
  • Метаданные класса должны будут считываться из файла базы данных каждый раз, когда вы снова открываете его. db4o также должен будет снова проанализировать структуру всех постоянных классов, когда они используются. Хотя обе операции выполняются довольно быстро, вам, вероятно, не нужны эти накладные расходы каждый раз, когда вы сохраняете один объект.
  • db4o имеет очень эффективные кэши для индексов классов и полей и для самого файла базы данных. Если вы закроете и снова откроете файл, вы им не воспользуетесь.
  • При настройке кода возможны сбои при работе с несколькими потоками. Что если два потока захотят открыть файл базы данных одновременно? Файлы базы данных db4o могут быть открыты только один раз. Можно выполнить несколько транзакций и несколько потоков для одного открытого экземпляра, а также использовать режим клиент / сервер, если вам нужно несколько транзакций.
  • Позже вы можете попробовать прозрачную активацию и прозрачную стойкость. Прозрачная активация лениво загружает элементы объекта при первом обращении к ним. Прозрачное постоянство автоматически сохраняет все объекты, которые были изменены в транзакции. Чтобы прозрачная активация (TA) и Transparent Persistence (TP) работали, вам обязательно нужно держать ObjectContainer открытым.

Вам не нужно беспокоиться о том, чтобы постоянно иметь открытый файл базы данных. Одной из ключевых целей db4o является встроенное использование в (мобильных) устройствах. Вот почему мы написали db4o таким образом, что вы можете в любое время выключить компьютер, не рискуя испортить базу данных, даже если файл все еще открыт.

Возможные причины, по которым вы получаете GenericObject вместо объекта Pilot:

  • Это может произойти, если имя сборки, содержащей объект Pilot, изменилось между двумя запусками, либо потому, что вы позволили VisualStudio автоматически генерировать имя, либо потому, что вы изменили его вручную.
  • Может быть, "db4o" является частью названия вашей сборки? Одна из последних сборок была слишком агрессивной при фильтрации внутренних классов. Это было исправлено довольно давно. Вы можете загрузить и попробовать последнюю версию, «разработка» или «производство» должны подойти.
  • В презентации, которую я когда-то делал, я однажды видел действительно странные симптомы, когда db4o ObjectContainers открывался в блоке "using". В любом случае, вы, вероятно, хотите работать без этого и постоянно держать объектный контейнер db4o открытым.
1 голос
/ 08 июня 2010

Можно повторно открыть базу данных несколько раз. Проблема будет в производительности и потере «идентичности». Также вы не можете сохранить ссылку на результат запроса и попытаться повторить его после закрытия БД (на основе вашего кода, похоже, что вы хотите это сделать).

GenericObjects создаются, когда класс не может быть найден.

Можете ли вы предоставить полный минималистский образец, который вам не подходит?

Кроме того, какую версию db4o вы используете?

Лучший

...