从天蓝色表存储中读取数据时出错

问题描述

我正在编写代码以从表存储中读取值。该代码类似于逐级打印树中的节点。

例如:

root

Level1child1-> Level1child2-> Level1child3

string tablename = "<table-name">;
string storageAccountName = "<storage-account-name";

var baseurl = @$"https://{storageAccountName}.table.core.windows.net/{tableName}()";
var sastoken = getAccountSASToken();
string filter = @"&$filter=PartitionKey%20eq%20'123'%20and%20RowKey%20eq%20'abc'";
baseurl = $"{baseurl}{sastoken}{filter}";
var data = HttpHelper.GetForOData(baseurl);
var responseData = data.Data.Replace(".","_");
var odata = JsonConvert.DeserializeObject<ODataResponse>(responseData);
Queue<int> strQ = new Queue<int>();
Console.WriteLine(odata.value[0].Email);
strQ.Enqueue(odata.value[0].TreeNodeID);

while (strQ.Any())
{
    var url = @$"https://{storageAccountName}.table.core.windows.net/{tableName}()";
    var token = _tableStorageRepository.GetAccountSASToken();
    filter = @"&$filter=ParentNodeId%20eq%20" + strQ.Peek();
    url = $"{url}{token}{filter}";
    data = HttpHelper.GetForOData(url);
    responseData = data.Data.Replace(".","_");
    odata = JsonConvert.DeserializeObject<ODataResponse>(responseData);

    foreach (var m in odata?.value)
    {
        Console.WriteLine(m.Email);
        strQ.Enqueue(m.TreeNodeID);
    }
    strQ.Dequeue();
}

    public class ODataResponse
    {
        public string odata_Metadata { get; set; }
        public List<ODatavalue> value { get; set; }
    }
    public class ODatavalue
    {
        public string odata_type { get; set; }
        public string odata_id { get; set; }
        public string odata_etag { get; set; }
        public string odata_editLink { get; set; }            
        public string RowKey { get; set; }            
        public string Email { get; set; }            
        public int ParentNodeID { get; set; }            
        public int TreeNodeID { get; set; }

    }

HttpHelper类的代码https://github.com/xyz92/httphelper/blob/master/HttpHelper.cs

我第一次运行此代码时,它仅打印根节点。

第二次运行此代码时,它打印了根节点和Level1child1节点。

在下一次运行中,它打印了根节点,Level1child1节点和Level1child2节点。

在某些运行中,最后一个节点Level1child3节点很少被打印。

代码中我缺少什么?

更新:

示例responseData:

{
    "odata_Metadata": "https://<storage-account-name>_table_core_windows_net/$Metadata#<table-name>","value": [{
            "odata_type": "<storage-account-name>_<table-name>","odata_id": "https://<storage-account-name>_table_core_windows_net/<table-name>(PartitionKey='123',RowKey='abc')","odata_etag": "W/\"datetime'2020-09-01T16%3A34%3A21_3342187Z'\"","odata_editLink": "<table-name>(PartitionKey='123',"PartitionKey": "123","RowKey": "abc","Timestamp@odata_type": "Edm_DateTime","Timestamp": "2020-09-01T16:34:21_3342187Z","Email": "email","ParentNodeID": 1,"TreeNodeID": 2
        }
    ]
}

表列:

enter image description here

表中的样本数据:

enter image description here

运行代码时对输出进行采样:

enter image description here

enter image description here

enter image description here

解决方法

根据我的测试,我无法在我的环境中重现您的问题。我的测试如下

表列:

enter image description here

表中的样本数据 enter image description here

代码我使用您的HttpHelper类发送请求

class Program
    {
        static async Task Main(string[] args)
        {
            string storageAccountName = "andyprivate" ;
            string tableName = "test";

            var baseurl = @$"https://{storageAccountName}.table.core.windows.net/{tableName}()";
            var sastoken = "";
            string filter = @"&$filter=PartitionKey%20eq%20'123'%20and%20RowKey%20eq%20'abc'";
            baseurl = $"{baseurl}{sastoken}{filter}";
            var data = HttpHelper.GetForOData(baseurl);
            var responseData = data.Data.Replace(".","_");
            var odata = JsonConvert.DeserializeObject<ODataResponse>(responseData);
            Queue<int> strQ = new Queue<int>();
            Console.WriteLine("----root----");
            Console.WriteLine(odata.value[0].Email);
            strQ.Enqueue(odata.value[0].TreeNodeID);
            while (strQ.Any())
            {
                int i = 0;
               
                var url = @$"https://{storageAccountName}.table.core.windows.net/{tableName}()";
                var token = "";
                filter = @$"&$filter=ParentNodeID eq {strQ.Peek()}";
                url = $"{ url}{token}{filter}";
                data = HttpHelper.GetForOData(url);
                responseData = data.Data.Replace(".","_");
                odata = JsonConvert.DeserializeObject<ODataResponse>(responseData);
                Console.WriteLine($"----TreeNode{strQ.Peek()}----");
                foreach (var m in odata?.value)
                {
                    if (i == 0) {
                        strQ.Enqueue(m.TreeNodeID);
                        i = 1;
                    }                   
                    Console.WriteLine(m.Email);
                    
                }
                strQ.Dequeue();
            }
            Console.ReadLine();
        }

      
    }
    public class ODataResponse
    {
        public string odata_metadata { get; set; }
        public List<ODatavalue> value { get; set; }
    }
    public class ODatavalue
    {
        public string odata_type { get; set; }
        public string odata_id { get; set; }
        public string odata_etag { get; set; }
        public string odata_editLink { get; set; }
        public string RowKey { get; set; }
        public string Email { get; set; }
        public int ParentNodeID { get; set; }
        public int TreeNodeID { get; set; }

    }

enter image description here


更新

我的测试代码

Rest API(我使用您的HttpHelper类发送请求)

class Program
    {
        static async Task Main(string[] args)
        {
            string storageAccountName = "andyprivate" ;
            string tableName = "test";

            var baseurl = @$"https://{storageAccountName}.table.core.windows.net/{tableName}()";
            var sastoken = "";
            string filter = @"&$filter=PartitionKey%20eq%20'123'%20and%20RowKey%20eq%20'abc'";
            baseurl = $"{baseurl}{sastoken}{filter}";
            var data = HttpHelper.GetForOData(baseurl);
            var responseData = data.Data.Replace(".","_");
            var odata = JsonConvert.DeserializeObject<ODataResponse>(responseData);
            Queue<int> strQ = new Queue<int>();
            Console.WriteLine("----root----");
            Console.WriteLine(odata.value[0].Email);
            strQ.Enqueue(odata.value[0].TreeNodeID);
            while (strQ.Any())
            {
                int i = 0;

                var url = @$"https://{storageAccountName}.table.core.windows.net/{tableName}()";
                var token = "";
                filter = @$"&$filter=ParentNodeID eq {strQ.Peek()}";
                url = $"{ url}{token}{filter}";
                data = HttpHelper.GetForOData(url);
                responseData = data.Data.Replace(".","_");
                odata = JsonConvert.DeserializeObject<ODataResponse>(responseData);
                Console.WriteLine($"----TreeNode{strQ.Peek()}----");
                foreach (var m in odata?.value)
                {
                    if (i == 0) {
                        strQ.Enqueue(m.TreeNodeID);
                        i = 1;
                    }                   
                    Console.WriteLine(m.Email);

                }
                strQ.Dequeue();
            }
            Console.ReadLine();
        }


    }
    public class ODataResponse
    {
        public string odata_metadata { get; set; }
        public List<ODatavalue> value { get; set; }
    }
    public class ODatavalue
    {
        public string odata_type { get; set; }
        public string odata_id { get; set; }
        public string odata_etag { get; set; }
        public string odata_editLink { get; set; }
        public string RowKey { get; set; }
        public string Email { get; set; }
        public int ParentNodeID { get; set; }
        public int TreeNodeID { get; set; }

    }

SDK。我使用了Microsoft.Azure.Cosmos.Table

string storageAccountName = "andyprivate";
            string accountKey ="";
            string tableName = "test";
            CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials(storageAccountName,accountKey),true);
            CloudTableClient tableClient = storageAccount.CreateCloudTableClient(new TableClientConfiguration());
            CloudTable table = tableClient.GetTableReference(tableName);
            TableOperation retrieveOperation = TableOperation.Retrieve<CustomEntity>("123","abc");
            TableResult result = await table.ExecuteAsync(retrieveOperation);
            CustomEntity entity = result.Result as CustomEntity;
            Queue<int> strQ = new Queue<int>();
            Console.WriteLine("----root----");
            Console.WriteLine(entity.Email);
            strQ.Enqueue(entity.TreeNodeID);
            while (strQ.Any()) {
                int i = 0;
                TableQuery<CustomEntity> query = new TableQuery<CustomEntity>()
                    .Where(                      
                          TableQuery.GenerateFilterConditionForInt("ParentNodeID",QueryComparisons.Equal,strQ.Peek())
                    );
                Console.WriteLine($"----TreeNode{strQ.Peek()}----");
                foreach (CustomEntity m in table.ExecuteQuery(query) ) {
                    Console.WriteLine(m.Email);
                    if (i == 0) {
                        strQ.Enqueue(m.TreeNodeID);
                        i = 1;
                    }
                } 
                strQ.Dequeue();
            }

enter image description here