0

我是 NoSql 概念的新手。来自“ModelFirst”的思维定势,我通常首先设计我的模型。我有一个模型如下。

public class Book
{
    public string Name { get; set; }
    [EntityPropertyConverter(typeof(Category))]
    public List<Category> Categories { get; set; }
}
public class Category
{
    public string Name { get; set; }
}

学生类是一个复杂的类型,并且

[EntityPropertyConverter]

属性有助于在写入 Azure 表之前序列化类别并在回读时反序列化。

一本书可以属于多个类别。我的问题是,如果有人必须按 n 个类别中的一个来搜索一本书,我们该怎么做。

Azure Table 支持如下查询

TableQuery.GenerateFilterCondition("Categories", QueryComparisons.Equal, JsonConvert.SerializeObject(???))

但是这样我就无法得到所需的结果。

如果我的整体方法不正确,请发表评论。

4

2 回答 2

1

在 Azure 表中查询复杂类型

据我了解,目前不支持。如果我们想将复杂类型的数据保存到表存储中,我们需要将SerializeObject转为字符串并存储到表存储中

根据支持的表比较运算符,我们可以知道它不支持contains. 似乎我们没有办法过滤预期的结果。

如果 Azure cosmos DB(table API) 是可能的,我建议您可以尝试一下。

文件格式:

{
    "id": "test",
    "Book": {
        "Categories": [
            {
                "Name": "Category1"
            },
            {
                "Name": "Category2"
            }
        ],
        "Name": "book1"
    }
}

请求参数:

SELECT * FROM root WHERE (ARRAY_CONTAINS(root.Book.Categories, {"Name": "Category2"}, true)or ARRAY_CONTAINS(root.Book.Categories, {"Name": "Category4"}, true)) 

从 Azure 门户查询:

![在此处输入图像描述

于 2018-05-28T09:34:54.103 回答
0

有一种方法可以将复杂对象写入和查询到表存储,这是 TableEntity.FlattenSDK 中首先展平对象的方法。TableEntity.ConvertBack方法将其读回并转换为原始复杂对象。它不会进行完整的序列化,它会将本机属性保留EntityProperty在展平对象上,因此可以单独查询每个属性。

也就是说,当前版本的apiIEnumerable/ICollection不支持属性类型。TableEntity.Flatten但是,nuget 包 Object Flattener Recomposer 2.0 版支持集合/可枚举/索引类型属性:

https://www.nuget.org/packages/ObjectFlatenerRecomposer/

因此,如果您的对象具有那些类型的索引/可枚举类型属性,则可以使用此 nuget 将复杂类型写入表存储。这个 nuget 包与 SDK 中的 api 执行相同的操作(它是TableEntity.Flatten/ ConvertBackmethods 背后的原始代码),但此外,它会在写入表存储之前将可枚举/集合类型属性转换为 json 字符串,并创建原始在透明地从表中读取复杂对象时,您无需担心将展平对象反序列化回原始复杂类型。

回到您最初的问题,可以通过我在 SDK 中提到的方法或 ObjectFlatenerRecomposer api 的最新 nuget 包将复杂的对象写入和读取到表存储中。尽管如果您想从 List 类型属性中查询单个对象,这仍然会很棘手,因为我提到的 List 将采用表上的 json 字符串格式。

于 2018-05-31T09:25:07.253 回答