1

我有一个运行 .net 4.0 的服务器,它正在创建一个 db4o 数据库并将其发送到客户端。客户端运行.net 3.5,无法打开数据库(这曾经在服务器也是3.5时工作)。

客户端抛出一个Db4oIOException堆栈跟踪,如下所示:

at Db4objects.Db4o.IO.ReadOnlyBin.Write(Int64 position, Byte[] bytes, Int32 bytesToWrite)
at Db4objects.Db4o.IO.BinDecorator.Write(Int64 position, Byte[] bytes, Int32 bytesToWrite)
at Db4objects.Db4o.IO.BlockAwareBin.BlockWrite(Int32 address, Int32 offset, Byte[] bytes, Int32 length)
at Db4objects.Db4o.Internal.IoAdaptedObjectContainer.WriteBytes(ByteArrayBuffer buffer, Int32 blockedAddress, Int32 addressOffset)
at Db4objects.Db4o.Internal.LocalObjectContainer.WritePointer(Int32 id, Slot slot)
at Db4objects.Db4o.Internal.LocalObjectContainer.AllocatePointerSlot()
at Db4objects.Db4o.Internal.Ids.PointerBasedIdSystem.NewId()
at Db4objects.Db4o.Internal.Ids.TransactionalIdSystemImpl.AcquireId()
at Db4objects.Db4o.Internal.Ids.TransactionalIdSystemImpl.NewId(SlotChangeFactory slotChangeFactory)
at Db4objects.Db4o.Internal.PersistentBase.Write(Transaction trans)
...

关于如何以兼容格式保存数据库或无错误加载的任何想法?

附加信息

我似乎没有存储任何 .net 4.0 特定数据。在 LINQPad 中打开数据库并浏览它只显示我自己的自定义类(它们都是在 3.5 下构建的)。

似乎 db4o 试图写入的对象/类型是System.Reflection.Cache.InternalCache. db4o 的 Jira 上存在一个可能相关(或可能不相关)的问题。

还有一个带有异常相似堆栈跟踪的错误

使用Db4oEmbedded.OpenFile(Db4oConfiguration.Default(), path)会导致此异常。如果我Db4oEmbedded.OpenFile(path)改为使用,则不会引发异常,但恢复的数据中会丢失一些对象。

4

1 回答 1

1

看起来 db4o 正在尝试在只读数据库 (ReadOnlyBin) 上创建元数据。

您是否以只读模式打开数据库?

我可以使用以下代码重现您的问题(您甚至不需要拥有不同版本的框架):

  • 使用 ProxyTuple = System.Tuple 运行应用程序(以创建数据库)
  • 使用 ProxyTyple = Db4objects.Db4o.Foundation.Tuple 再次运行它

在这种情况下,问题是我正在使用 System.Tuple(在 .Net 4.0 上可用)创建数据库,并尝试使用 Db4o 元组实现在 .Net 3.5 上打开数据库(因为 .Net 3.5 上不存在元组类型) .

你可能会遇到类似的情况。

using System;
using System.IO;
using Db4objects.Db4o;
using Db4objects.Db4o.Config;

using ProxyTuple = Db4objects.Db4o.Foundation.Tuple<int, string>;
//using ProxyTuple = System.Tuple<int, string>;

namespace db4oVersionTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var databaseFileName = "test.odb";
            if (!typeof(ProxyTuple).FullName.Contains("Db4o"))
            {
                File.Delete(databaseFileName);

                using (var db = Db4oEmbedded.OpenFile(databaseFileName))
                {
                    db.Store(new Item { value = 42, tuple = new ProxyTuple(42, "forty two")});
                }
            }
            else
            {
                using (var db = Db4oEmbedded.OpenFile(NewConfiguration(), databaseFileName))
                {
                    foreach (var item in db.Query<Item>())
                    {
                        Console.WriteLine(item);
                    }
                }
            }
        }

        private static IEmbeddedConfiguration NewConfiguration()
        {
            var configuration = Db4oEmbedded.NewConfiguration();
            configuration.File.ReadOnly = true;

            return configuration;
        }
    }

    class Item
    {
        public int value;
        public ProxyTuple tuple;

        public override string ToString()
        {
            return value + " " + tuple;
        }
    }
}
于 2013-04-02T09:08:34.763 回答