当我阅读有关 Document Hierarchy 的 Maven 文档时,我认为调用通用参数是基类的 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.
这对我来说听起来会使用反射,所以我不必指定每个子类。我的层次结构是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 不支持“结构类型”,但将来可能
- 在内部,子类类型文档也存储为身份映射机制中的父类型。
- 添加此功能需要花费很多很多时间在我的桌子上敲打我的头。
最糟糕的部分似乎是“此时,您只能在顶部指定“可搜索”字段,基本类型”,但我Query<>在用户名上做了一个,它在基本类型中不存在CoreObject(它存在于Actor)。所以我不确定这意味着什么?
更新
Marten 必须用“可搜索”表示“可索引”是什么意思?因为我不能再在子类中存在的属性上创建索引,看来。