NDatabase 在 Order By 上崩溃
本文关键字:崩溃 By Order NDatabase | 更新日期: 2023-09-27 18:36:59
我正在使用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();
}
这会在ToList()
调用上引发NDatabase.Exceptions.OdbRuntimeException
。深入研究异常属性会给出消息
"NDatabase 抛出异常错误:222:不支持操作: 复制到"
但是,如果我注释掉q.Descend("Timestamp").OrderAscending();
行,那么它工作正常 - 尽管它显然不是有序的。
请问谁能帮忙阐明这一点?
例外情况是告诉您 NDatabase 的基本实现ICollection<T>
(AbstractBTreeCollection<T>
) 不支持方法 CopyTo()
,该方法由您正在使用的 LINQ 扩展方法ToList()
调用。
那么问题来了,为什么这只发生在你使用 OrderByAscending 做中介工作时,而不是直接在查询结果上?
查看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
。 - 如果您没有订单,您将获得一个
SimpleList
或LazySimpleListFromOid
的实例,它们确实支持CopyTo
。
查看NDatabase的示例,他们不希望您调用ToList()
:https://ndatabase.codeplex.com/wikipage?title=5-minutes-tutorial
这是一个相当痛苦的实现细微差别。您可能希望将其作为他们的问题提出。