代码之家  ›  专栏  ›  技术社区  ›  Ted

Marten:在构造函数中调用addSubassHierarchy()不会导致查询结果<T>

  •  0
  • Ted  · 技术社区  · 6 年前

    当我读到小牛的时候 docs regarding Document Hierarchy ,我认为在泛型参数是基类的情况下调用addSubasssHierarchy()将自动映射所有子类型。文件内容如下:

    // 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 .

    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();
            }
    

    查询<T> 也失败了,就像这个:

            using (var session = store.LightweightSession())
            {
                List<Customer> list = session.Query<Customer>().ToList();
                return list;
            }
    

    _.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不支持“结构类型”,但是可以
    • 在内部,子类类型文档也作为父类型存储在标识映射机制中。
    • 为了增加这个功能,我需要花上好几个小时把我的头敲打在桌子上。

    最糟糕的部分似乎是“在这一点上,您只能在顶部指定”Searchable“字段,基本类型”,但是我做了一个 Query<> 关于用户名,它不存在于基类型中 CoreObject Actor ). 所以我不知道那是什么意思?

    更新

    1 回复  |  直到 5 年前
        1
  •  0
  •   Ted    6 年前

    所以,我想我得到了答案:

    添加以下行,将假定所有子类都持久化在顶级表中,因此 Actor Customer 都会坚持到 mt_doc_coreobject

    所以,如果您添加下面的行,Marten会假设是这样的,但是如果objets已经存在于它们自己的表中(在添加下面的行之前),则不会找到任何结果。

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

    然后将要求您重新插入对象,然后它们将出现在 mt_doc_核心对象 .

    推荐文章