我是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; }
}
Student class是一个复杂的类型
[EntityPropertyConverter]
属性有助于在写入Azure表之前序列化类别,并在回读时反序列化。
一本书可以属于多个类别。我的问题是,如果有人必须通过n个类别中的一个来搜索书籍,我们该怎么做呢。
Azure Table支持如下所示的查询
TableQuery.GenerateFilterCondition("Categories", QueryComparisons.Equal, JsonConvert.SerializeObject(???))
但有了这个我无法得到所需的结果。
如果我的整体方法不正确,请发表评论。
答案 0 :(得分:1)
在Azure表中查询复杂类型
根据我的理解,目前不支持。 如果我们想将复杂类型数据保存到表存储,我们需要将SerializeObject串起来并将其存储到表存储
根据 supported table comparison operators,我们可以知道它不支持contains
。似乎我们无法过滤预期的结果。
如果可以使用Azure cosmos DB(表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门户网站查询:
答案 1 :(得分:0)
有一种方法可以将复杂对象写入和查询到表存储,这是SDK中的TableEntity.Flatten
方法,可以首先展平您的对象。 TableEntity.ConvertBack
方法将其读回并转换为原始复杂对象。它不执行完整序列化,它在展平对象上将本机属性保留为EntityProperty
,因此可以单独查询每个属性。
那就是当前版本的IEnumerable/ICollection
api不支持TableEntity.Flatten
类型的属性。但是,nuget包Object Flattener Recomposer 2.0版支持collection / enumerable / indexed类型属性:
https://www.nuget.org/packages/ObjectFlattenerRecomposer/
因此,如果对象具有这些类型的索引/可枚举类型属性,则可以使用此nuget将复杂类型写入表存储。这个nuget包与SDK中的api相同(它是TableEntity.Flatten
/ ConvertBack
方法背后的原始代码),但此外它还会将枚举/集合类型属性转换为json字符串写入表存储并且它在透明地从表中读取时创建原始复杂对象,您不必担心将展平对象反序列化回原始复杂类型。
回到原来的问题,可以通过我在SDK中提到的方法或ObjectFlattenerRecomposer api的最新nuget包来编写和读取复杂对象到表存储。虽然如果你想从List类型属性中查询单个对象,它仍然会很棘手,因为我提到的List将采用表格中json字符串的格式。