0

当我阅读有关 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 必须用“可搜索”表示“可索引”是什么意思?因为我不能再在子类中存在的属性上创建索引,看来。

4

1 回答 1

0

所以,我想我有答案:

添加以下行,将假设所有子类都保存在顶级表中,因此所有子类都ActorCustomer保存在mt_doc_coreobject表中,而不是它们自己的特定表中。

因此,如果您添加下面的行,Marten 会假设是这种情况,但如果对象已经保存在自己的表中(在添加下面的行之前),则不会找到任何结果。

所以,这一行:

so.Schema.For<CoreObject>().AddSubClassHierarchy();

然后将要求您重新插入对象,然后它们会出现在mt_doc_coreobject.

于 2018-08-17T02:55:51.700 回答