当我阅读Maven docs regarding Document Hierarchy时,我认为调用AddSubClassHierarchy()(泛型参数是基类)会自动映射所有子类型。文档读为:
// Alternatively, you can use the following:
// _.Schema.For<ISmurf>().AddSubClassHierarchy();
// this, however, will use the assembly
// of type ISmurf to get all its' subclasses/implementations.
// In projects with many types, this approach will be undvisable.
在我看来,将使用Reflection,因此不必指定每个子类。我的等级为CoreObject-->Actor-->Customer
。
但是当我添加AddSubClassHierarchy时,Query<T>
失败并且什么也不返回:
store = DocumentStore.For(_ =>
{
// Marten will create any new objects that are missing,
// attempt to update tables if it can, but drop and replace
// tables that it cannot patch.
_.Connection("host=localhost;database=marten;password=root;username=postgres");
_.Schema.For<Customer>().Index(x => x.PopulationRegistryNumber);
_.Schema.For<CoreObject>().AddSubClassHierarchy(); // CoreObject is base class to Actor, that is base class for Customer
_.AutoCreateSchemaObjects = AutoCreate.CreateOrUpdate;
});
然后尝试时:
using (var session = store.OpenSession())
{
list = session.Query<Actor>().Where(a => a.Username == "asdasd").ToList();
}
失败,不返回任何项目。其他所有Query<T>
也会失败,就像这样:
using (var session = store.LightweightSession())
{
List<Customer> list = session.Query<Customer>().ToList();
return list;
}
列表将包含0个元素。如果删除_.Schema.For<CoreObject>().AddSubClassHierarchy();
,我将从session.Query<Customer>()
获得结果。
我试图按照杰里米所说的去做;手动定义层次结构,如下所示:
public MartenDbHandler()
{
StoreOptions so = new StoreOptions();
// here it is: CoreObject-->Actor-->Customer
so.Schema.For<CoreObject>().AddSubClassHierarchy(typeof(Actor), typeof(Customer));
so.Connection("host=localhost;database=marten;password=root;username=postgres");
so.AutoCreateSchemaObjects = AutoCreate.CreateOrUpdate;
SetTableMeta(so);
store = new DocumentStore(so);
}
起初,没有变化。我需要清除并再次插入对象。然后我意识到,所有对象最终都在一个表中:mt_doc_coreobject
当我搜索时,它会起作用:
List<Actor> list3 = martenDbHandler.Select<Actor>(c => c.Username == "YS3M");
Console.WriteLine($"SELECT Actor {list3.Count}"); // = 1
但是我当然知道将所有对象放在一个表中是一个简单的解决方法,但是我想我也阅读了其他一些警告,但我不确定我是否正确解释了
类型层次结构需要注意几件事:
- 自动将抽象类型或接口的文档类型定为层次结构
- 如果要将具体类型用作层次结构的基类,则需要通过添加子类来显式配置该类,如上所示
- 目前,您只能在顶部基本类型中指定“可搜索”字段
- 子类文档类型必须可以转换为顶级类型。如 目前,Marten不支持“结构化类型”,但可能 未来
- 在内部,子类类型文档也作为父类型存储在Identity Map机制中。
- 要添加此功能,需要很多时间在桌子上敲打我的头。
最糟糕的部分似乎是“这时,您只能在顶部,基本类型指定“ Searchable”字段”,但是我在用户名上做了一个Query<>
,但该用户名在基础中不存在类型CoreObject
(存在于Actor
中)。所以我不确定这意味着什么?
Marten所说的“可搜索的”必须是“可索引的”?因为我无法再在子类中存在的属性上创建索引,所以。
答案 0 :(得分:0)
所以,我想我有答案:
添加以下行,将假定所有子类都保留在顶级表中,因此所有Actor
和Customer
都将保留在mt_doc_coreobject
表中,而不是他们自己的特定表格。
因此,如果添加下面的行,Marten会是这种情况,但是如果对象已经保留在自己的表中(添加下面的行之前),则不会找到结果。
因此,这一行:
so.Schema.For<CoreObject>().AddSubClassHierarchy();
然后将要求您重新插入对象,然后它们出现在mt_doc_coreobject
中。