从3.5中的.net 4.0下的db4o加载数据

时间:2013-04-01 22:06:02

标签: .net db4o

我有一台运行.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。有issue on db4o's Jira可能相关(或可能不相关)。

还有bug filed with an eerily similar stack trace

使用Db4oEmbedded.OpenFile(Db4oConfiguration.Default(), path)会导致此异常。如果我改为使用Db4oEmbedded.OpenFile(path),则不会抛出异常,但恢复的数据中缺少某些对象。

1 个答案:

答案 0 :(得分:1)

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

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

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

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

在这种情况下的问题是我正在使用System.Tuple创建数据库(在.Net 4.0上可用)并尝试使用Db4o元组实现在.Net 3.5上打开数据库(因为Tuple类型不存在)。净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;
        }
    }
}