我有一台运行.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)
,则不会抛出异常,但恢复的数据中缺少某些对象。
答案 0 :(得分:1)
看起来db4o正在尝试在只读db(ReadOnlyBin)上创建元数据。
您是否以只读模式打开数据库?
我可以使用以下代码重现您的问题(您甚至不需要拥有不同版本的框架):
在这种情况下的问题是我正在使用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;
}
}
}