【问题标题】:Loading data from db4o under .net 4.0 in 3.5在 .net 4.0 下从 db4o 加载数据 3.5
【发布时间】:2013-04-02 22:09:20
【问题描述】:

我有一个运行 .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),则不会引发异常,但恢复的数据中会丢失一些对象。

【问题讨论】:

    标签: .net db4o


    【解决方案1】:

    看起来 db4o 正在尝试在只读数据库 (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;
            }
        }
    }
    

    【讨论】:

    • 好的,关闭只读确实消除了异常。现在,恢复的数据中缺少一些对象。奇怪的是,据我所知,我只是将自己的(3.5 兼容)对象保存到数据库中,而不使用任何类型别名。感谢您详细说明如何配置连接,不知道该怎么做!
    • 如果您可以使用非常简单的程序集(使用导致问题的最简单的对象模型)重现此问题,我可以对其进行调试并尝试理解。
    • 最后,我认为 db4o 对我们在这里想要实现的目标来说太重了,所以我已经切换到 .net 序列化。不过,感谢您的回答......肯定学到了一些关于 db4o 的知识,我相信它会帮助其他人解决同样的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-07
    • 2012-12-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多