如何检查 BsonDocument 中的嵌套 属性 - 包含不起作用

How to check for nested property in BsonDocument - Contains doesn't work

当我编写代码来获取嵌套的 属性 时,当整个路径不存在时它会失败 - 这很公平 bsonDoc["Meeting"]["Session"]["Time"]

我看不出有什么方法可以防止这种情况发生,写 bsonDoc.Contains("Meeting.Session.Time") returns false 即使它存在

bsonDoc.Contains("Time") 也 returns 失败,即使它确实存在,所以它甚至不能检查字段 属性,如果它是嵌套的......?

文档甚至代码都不知道如何做我需要的事情。不确定是否可能。

有没有办法为嵌套的 bson 文档属性编写保护子句 - 即 BsonDocument class 是否具有嵌套的键检查机制?

我认为 BsonDocument 中没有任何方法支持使用嵌套的 属性.

获取 element/value

但是你可以实现logic/extension方法来处理:

概念:

  1. 用'.'分割键。

  2. First-level 搜索。

    2.1 首先 chainKey 将从 BsonDocument 通过 TryGetValue 搜索。

    2.2 如果键已经存在,@value (BsonValue) 将包含值(查询嵌套级别时需要)。

    2.3 如果key不存在,则跳出循环逻辑

  3. Second-level 或进一步搜索

    3.1 概念与2相同,只是会从BsonValue开始搜索(如2.2所述)。

public static class BsonDocumentExtensions
{
    public static bool TryGetChainedValue(this BsonDocument doc, string key, out BsonValue @value)
    {
        @value = default;
        // Get key, value from passed BsonDocument for first time, then refer to BsonValue to get key, value for nested property
        bool first = true;
        
        try
        {
            if (String.IsNullOrWhiteSpace(key))
                return false;
        
            string[] chainedKeys = key.Split(".").ToArray();
            
            bool hasKey = false;
            foreach (var chainKey in chainedKeys)
            {       
                if (first)
                {
                    hasKey = doc.TryGetValue(chainKey, out @value);
                    
                    first = false;
                }
                else
                {
                    hasKey = (@value.ToBsonDocument()).TryGetValue(chainKey, out @value);
                }

                // Throw exception if key not existed.
                if (!hasKey)
                    throw new Exception();
            }
        
            return true;
        }
        catch
        {           
            @value = default;
            return false;   
        }
    }
}

Sample .NET Fiddle


上面的概念和下面的多重if逻辑是一样的:

if (doc.TryGetValue("Meeting", out BsonValue meetingValue))
{
    if ((meetingValue.ToBsonDocument()).TryGetValue("Session", out BsonValue sessionValue))
    {
        if ((sessionValue.ToBsonDocument()).TryGetValue("Time", out BsonValue timeValue))
        {
            Console.WriteLine(timeValue);
        }
    }
}