1

我正在使用 NDatabase 来做一些非常简单的对象存储——基本上是构建一个持久的工作队列。计划是创建一组对象,将它们保存到磁盘,然后按其中一个属性排序读取它们。我无法让“排序”部分工作 - NDatabase 引发异常。

这是我要保留的对象的超类型:

public abstract class Instruction: IComparable, IComparable<Instruction>
{
    public virtual DateTime Timestamp
    {
        get;
        set;
    }

    public int CompareTo(Instruction other)
    {
        if (this.Timestamp.Equals(other.Timestamp))
            return 0;

        return (this.Timestamp < other.Timestamp) ? -1 : 1;
    }

    public int CompareTo(object obj)
    {
        var other = obj as Instruction;
        return other == null ? -1 : this.CompareTo(other);
    }
}

这是我创建对象存储的方式:

using (var odb = OdbFactory.Open(storeName))
{
    odb.IndexManagerFor<Instruction>().AddIndexOn("TimestampIndex", "Timestamp");
    foreach (var instruction in instructions)
    {
        odb.Store(instruction);
    }
    odb.IndexManagerFor<Instruction>().RebuildIndex("TimestampIndex");
}

以下是稍后检索商店的方式:

lock (this.odb)
{
    var q = odb.Query<T>();
    q.Descend("Timestamp").OrderAscending();
    var objectSet = q.Execute<T>(true, 0, maxCount);
    instructions = objectSet.ToList();

    foreach (var instruction in instructions)
    {
        odb.Delete(instruction);
    }

    odb.IndexManagerFor<Instruction>().RebuildIndex("TimestampIndex");

    odb.Commit();
}

NDatabase.Exceptions.OdbRuntimeException这会引发ToList()通话。挖掘异常属性会给出消息

“NDatabase 已引发异常错误:222:不支持操作:CopyTo”

但是,如果我注释掉该行,q.Descend("Timestamp").OrderAscending();那么它可以正常工作 - 尽管它显然没有被订购。

任何人都可以帮助阐明这一点吗?

4

1 回答 1

5

例外是告诉您 NDatabase 的ICollection<T>( AbstractBTreeCollection<T>) 的基本实现不支持您正在使用CopyTo()的 LINQ 扩展方法调用的方法。ToList()

那么问题就变成了,为什么这只发生在你使用 OrderByAscending 做中间工作时,而不是直接在 Query 的结果上?

查看 NDatabase 的源代码,我可以明白为什么: http ://ndatabase.codeplex.com/SourceControl/latest

if (_inMemory)
{
    if (_query != null && _query.HasOrderBy())
        _result = new InMemoryBTreeCollection<T>(_query.GetOrderByType());
    else
        _result = new SimpleList<T>();
}
else
{
    // result = new InMemoryBTreeCollection((int) nbObjects);
    if (_query != null && _query.HasOrderBy())
        _result = new LazyBTreeCollection<T>(_storageEngine, _returnObjects);
    else
        _result = new LazySimpleListFromOid<T>(_storageEngine, _returnObjects);
}

QueryResultAction<T>.Start()

  • 如果你有一个订单,你会得到一个 AbstractBTreeCollection不支持的实现实例CopyTo
  • 如果你没有 order by,你会得到一个SimpleListor的实例LazySimpleListFromOid,它支持CopyTo.

查看 NDatabase 的示例,他们不希望您致电ToList()https ://ndatabase.codeplex.com/wikipage?title=5-minutes-tutorial

这是一个相当痛苦的实现细微差别。您可能想向他们提出这个问题。

于 2015-01-16T13:03:23.210 回答