即使没有结果,Cosmos 也会在 ReadItemAsync 上反序列化

问题描述 投票:0回答:1

我看到一个问题(?),我的查询不返回任何数据,但仍被反序列化为类。为了说明这一点,请考虑以下模型:

public class Employee
{
    public Guid Id {get;set;}
    public string Name {get;set;}
    
    public Manager Manager {get;set;}
}

public string Manager
{
    public Guid Id {get;set;}
    public string Name {get;set;}
}


public async Task<Manager?> GetManagerAsync(Guid employeeId, CancellationToken cancellationToken)
{
    var query = $"SELECT value(c.manager) FROM c WHERE c.id = 'cc68c329-38f2-4de7-896c-69ab7cc0d80a'";
    return container.ReadItemAsync<Manager?>(employeeId.ToString(), new PartitionKey(employeeId.ToString()), cancellationToken: cancellationToken)
}

现在考虑容器内的以下记录,该容器根本没有管理器节点。

{
    "id": "cc68c329-38f2-4de7-896c-69ab7cc0d80a",
    "name": "mike"
}

我可以通过直接在 Cosmos DB 中执行查询来验证是否缺少结果。但是,当 ReadItemAsync 在 GetManagerAsync 中执行时,它会获取所有根级别属性(id 和 name)并将它们映射到 Manager 类中,即使查询未返回任何数据。

我在这里不明白什么以及如何正确执行此操作,我可以返回空对象而不是将根属性属性映射到子节点请求?

azure-cosmosdb azure-cosmosdb-sqlapi
1个回答
0
投票

您创建了一个查询并将其保存到变量

query
中,但从未实际使用它。如果您想使用字符串查询来查询容器,您应该调用方法
container.GetItemQueryIterator

相反,您使用的是点读取,它返回文字对象,而无法对数据执行任何转换。考虑到您的模型实际上应该比执行查询更快,所以这很好,但是您必须将其反序列化为项目的实际类:

var employee = container.ReadItemAsync<Employee>( //<- Used the Employee class
    employeeId.ToString(), 
    new PartitionKey(employeeId.ToString()),
    cancellationToken: cancellationToken);
return employee.Manager;

根据您的示例数据,

Manager
属性应该可以为空:

public class Employee
{
    public Guid Id {get;set;}
    public string Name {get;set;}
    
    public Manager? Manager {get;set;} //<- added the ?
}
© www.soinside.com 2019 - 2024. All rights reserved.