在构造函数中调用 AddSubClassHierarchy() 导致 Query<T> 中没有结果
Calling AddSubClassHierarchy() in constructor causes no results in Query<T>
当我阅读 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.
我觉得应该使用反射,所以我不必指定每个子类。我的层次结构是 CoreObject-->Actor-->Customer
.
但是当我添加 AddSubClassHierarchy 时,Query<T>
失败并且 returns 什么都没有:
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();
}
它失败了,returns 没有项目。所有其他 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);
}
起初,没有任何变化。我需要再次清除并插入对象。然后我意识到所有对象最终都在 one table: mt_doc_coreobject
然后当我搜索时,它起作用了:
List<Actor> list3 = martenDbHandler.Select<Actor>(c => c.Username == "YS3M");
Console.WriteLine($"SELECT Actor {list3.Count}"); // = 1
但我当然意识到将所有对象放在一个 table 中是一个简单的解决方法,但我认为我阅读了其他一些警告,我不确定我是否解释正确:
There's a couple things to be aware of with type hierarchies:
- A document type that is either abstract or an interface is automatically ssumed to be a hierarchy
- If you want to use a concrete type as the base class for a hierarchy, you will need to explicitly configure that by adding the subclasses as shown above
- At this point, you can only specify "Searchable" fields on the top, base type
- The subclass document types must be convertable to the top level type. As
of right now, Marten does not support "structural typing", but may in
the future
- Internally, the subclass type documents are also stored as the parent type in the Identity Map mechanics.
- Many, many hours of banging my head on my desk were required to add this feature.
最糟糕的部分似乎是"At this point, you can only specify "顶部的可搜索“字段,基本类型”,但我在用户名上做了一个Query<>
,它在基本类型中不存在CoreObject
(它存在于Actor
)。所以我不确定那是什么意思?
更新
Marten 对 "searchable" 的意思是 "indexable"?因为我不能再在子类中存在的 属性 上创建索引,所以看起来。
所以,我想我有答案了:
添加以下行,将假定所有子类都持久化在顶层 table,因此所有 Actor
和 Customer
都将持久化在 [=13] =]table,而不是自己特定的tables.
所以,如果你添加下面的行,Marten 会假设是这种情况,但是如果对象已经在他们自己的 tables 中保存(在添加下面的行之前),则不会有结果成立。
因此,这一行:
so.Schema.For<CoreObject>().AddSubClassHierarchy();
然后将要求您重新插入对象,然后它们会出现在 mt_doc_coreobject
。
当我阅读 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.
我觉得应该使用反射,所以我不必指定每个子类。我的层次结构是 CoreObject-->Actor-->Customer
.
但是当我添加 AddSubClassHierarchy 时,Query<T>
失败并且 returns 什么都没有:
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();
}
它失败了,returns 没有项目。所有其他 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);
}
起初,没有任何变化。我需要再次清除并插入对象。然后我意识到所有对象最终都在 one table: mt_doc_coreobject
然后当我搜索时,它起作用了:
List<Actor> list3 = martenDbHandler.Select<Actor>(c => c.Username == "YS3M");
Console.WriteLine($"SELECT Actor {list3.Count}"); // = 1
但我当然意识到将所有对象放在一个 table 中是一个简单的解决方法,但我认为我阅读了其他一些警告,我不确定我是否解释正确:
There's a couple things to be aware of with type hierarchies:
- A document type that is either abstract or an interface is automatically ssumed to be a hierarchy
- If you want to use a concrete type as the base class for a hierarchy, you will need to explicitly configure that by adding the subclasses as shown above
- At this point, you can only specify "Searchable" fields on the top, base type
- The subclass document types must be convertable to the top level type. As of right now, Marten does not support "structural typing", but may in the future
- Internally, the subclass type documents are also stored as the parent type in the Identity Map mechanics.
- Many, many hours of banging my head on my desk were required to add this feature.
最糟糕的部分似乎是"At this point, you can only specify "顶部的可搜索“字段,基本类型”,但我在用户名上做了一个Query<>
,它在基本类型中不存在CoreObject
(它存在于Actor
)。所以我不确定那是什么意思?
更新
Marten 对 "searchable" 的意思是 "indexable"?因为我不能再在子类中存在的 属性 上创建索引,所以看起来。
所以,我想我有答案了:
添加以下行,将假定所有子类都持久化在顶层 table,因此所有 Actor
和 Customer
都将持久化在 [=13] =]table,而不是自己特定的tables.
所以,如果你添加下面的行,Marten 会假设是这种情况,但是如果对象已经在他们自己的 tables 中保存(在添加下面的行之前),则不会有结果成立。
因此,这一行:
so.Schema.For<CoreObject>().AddSubClassHierarchy();
然后将要求您重新插入对象,然后它们会出现在 mt_doc_coreobject
。