首页 > 解决方案 > 查询 Azure Cosmos DB 时并非所有属性都已映射

问题描述

我希望将 Azure CosmosDB 集成到我们的项目中。我为自己设定的目标是创建一个常见问题解答部分。我已经创建了表格,还添加了三个带有一些示例数据的集合。但是,在查询时,我可以看到并非所有属性都是从 JSON 开始映射的,因此我的查询没有给出任何结果。

我的模型类看起来像这样;

基础文档数据库实体

//This is a base class with some common shared properties
public abstract class BasisDocumentDBEntity
{
    [JsonProperty(PropertyName = "id")]
    public string Id { get; set; }

    [JsonProperty(PropertyName = "AangemaaktDoor")]
    public string AangemaaktDoor { get; set; }

    [JsonProperty(PropertyName = "AangemaaktOp")]
    public DateTime AangemaaktOp { get; set; }

    [JsonProperty(PropertyName = "GewijzigdOp")]
    public DateTime GewijzigdOp { get; set; }

    [JsonProperty(PropertyName = "GewijzigdDoor")]
    public string GewijzigdDoor { get; set; }
}

常见问题组

//I've came up with groups for FAQ. A group for example can be 'General' or 'Instruction video's'
public class FAQGroup : BasisDocumentDBEntity
{
    [JsonProperty(PropertyName = "Name")]
    public string Naam { get; set; }

    [JsonProperty(PropertyName = "Sections")]
    public List<FaqSection> Sections { get; set; }
}

常见问题解答部分

//Each group can contain one or more sections. And each section can contain one or more questions.
public class FaqSection : BasisDocumentDBEntity
{
    [JsonProperty(PropertyName = "Title")]
    public string Title { get; set; }

    [JsonProperty(PropertyName = "GroupId")]
    public string GroupId { get; set; }

    public FAQGroup Group { get; set; }

    [JsonProperty(PropertyName = "Questions")]
    public List<FAQQuestion> Questions { get; set; }
}

FAQ问题

//The actual question with the answer in it.
public class FAQQuestion : BasisDocumentDBEntity
{
    [JsonProperty(PropertyName = "Question")]
    public string Question { get; set; }

    [JsonProperty(PropertyName = "Answer")]
    public string Answer { get; set; }
}

我知道 CosmosDB 不是关系数据库类型。但是,如果我正确理解这篇文章,它应该是有可能的。

我的示例数据像这样存储在 CosmosDB 中;

团体:

{
"id": "1",
"Name": "Group 1",
"Sections": [
    1,
    2,
    3
],
"AangemaaktDoor": "user",
"AangemaaktOp": "2018-07-17 08:46",
"GewijzigdDoor": "user",
"GewijzigdOp": "2018-07-17 08:46",
"_rid": "<snip>",
"_self": "<snip>",
"_etag": "<snip>",
"_attachments": "attachments/",
"_ts": 1531818056
}

部分:

{
"id": "1",
"GroupId": "1",
"Title": "Common",
"Questions": [
    1,
    2,
    3
],
"AangemaaktDoor": "user",
"AangemaaktOp": "2018-07-17 08:46",
"GewijzigdDoor": "user",
"GewijzigdOp": "2018-07-17 08:46",
"_rid": "<snip>",
"_self": "<snip>",
"_etag": "<snip>",
"_attachments": "attachments/",
"_ts": 1531810510
}

问题:

{
"id": "1",
"Question": "My First Question is?",
"Answer": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam ultrices convallis sapien, sed vestibulum nisl mollis eget. Sed feugiat aliquet orci. Sed pretium feugiat enim, nec lacinia lacus eleifend et. Morbi vitae risus cursus sapien sodales ullamcorper id ut eros. Cras semper ipsum at congue tempus. Fusce hendrerit lorem lorem, non fermentum purus vehicula vel. Nulla aliquam lorem turpis, venenatis hendrerit ligula efficitur eget. Curabitur et erat quis diam interdum vestibulum. Proin congue feugiat dui, a feugiat nisi bibendum eget. Etiam congue orci eget magna efficitur semper. Sed mattis posuere ex, ut venenatis augue condimentum ac. Etiam tincidunt est odio, vitae interdum nibh mollis a. Aliquam id hendrerit dui, et bibendum justo. In hac habitasse platea dictumst.",
"AangemaaktDoor": "user",
"AangemaaktOp": "2018-07-17 08:46",
"GewijzigdDoor": "user",
"GewijzigdOp": "2018-07-17 08:46",
"_rid": "<snip>",
"_self": "<snip>",
"_etag": "<snip>",
"_attachments": "attachments/",
"_ts": 1531810570
}

我在 microsoft 文档中使用这篇文章作为参考。但我无法弄清楚为什么有些属性被填充而有些则没有。这就是我从我的存储库中得到的;

在此处输入图像描述

GroupId 和 Title 字段都不包含任何数据。我无法理解它。感觉很明显。有人知道吗?

更新

    public static async Task<IEnumerable<T>> GetItemsAsync(Expression<Func<T, bool>> 
predicate)
            {
            if (!_isInitialized) throw new InvalidOperationException("Repository must be initialized first!");

            //Query with filter >> returns nothing
            IDocumentQuery<T> query = _client.CreateDocumentQuery<T>(
                UriFactory.CreateDocumentCollectionUri(_databaseId, _collectionId),
                new FeedOptions { MaxItemCount = -1, EnableCrossPartitionQuery = true })
                .Where(predicate)
                .AsDocumentQuery();

            //Query without filter >> returns list with single section but empty 'GroupId' and empty 'Title'
            var xquery = _client.CreateDocumentQuery<T>(
            UriFactory.CreateDocumentCollectionUri(_databaseId, _collectionId),
            new FeedOptions { MaxItemCount = -1, EnableCrossPartitionQuery = true })
            .ToList();

            List<T> results = new List<T>();
            while (query.HasMoreResults)
            {
                results.AddRange(await query.ExecuteNextAsync<T>());
            }

            return results;
        }

更新 2

    public async Task<SectionDTO> GetFAQOverzicht(EFaqGroup faqGroup)
    {
        var faqSection = new SectionDTO();

        var groupId = ((int) faqGroup).ToString();
        var section = await DocumentDBRepository<FaqSection>.GetItemsAsync(faq => faq.GroupId == groupId);

        return faqSection;
    }

标签: c#azureazure-cosmosdbazure-cosmosdb-sqlapi

解决方案


CosmosDB 不是您已经说过的关系数据库。您使用的 CosmosDB SDK 不是 ORM。它只是 CosmosDB API 的一个包装器。

这意味着除非您使用连接或执行多个查询来进行检索,否则您不能只从它们各自的集合中获取其他对象。

仅仅因为您有一个包含数字的 GroupId 属性并不意味着 Section 集合与 Group 集合有任何关系。它不是实体框架。对于 CosmosDB 和 SDK,它们只是两个独立的集合,它们之间没有任何关系。

为了做你想做的事,你要么需要做多个查询来填充你正在检索的对象(不推荐每个子对象一个),要么使用 CosmosDB SQL 连接到其他两个表并将检索到的结果映射到你的对象.


推荐阅读