Search code examples
c#azure-data-exploreridatareader

Converting Kusto client response to list of objects returns empty objects


I am trying to convert the response received from running a Kusto query in which I am retrieving the schema of a table. My Kusto query looks like this:

tableName | getschema

The response for such a query, as seen in the Kusto Explorer looks something like this (incomplete)

enter image description here

Back in my C# code I have defined the following class:

 public class DatasetColumn
    {
        /// <summary>
        /// Name of the column
        /// </summary>
        public string? ColumnName { get; set; }

        /// <summary>
        /// Position of this column within the schema
        /// </summary>
        public int ColumnOrdinal { get; set; }

        /// <summary>
        /// Type of data contained in this column
        /// </summary>
        public string? DataType { get; set; }

        /// <summary>
        /// Type of data contained in this column
        /// </summary>
        public string? ColumnType { get; set; }
    }

And I am attempting to just retrieve a list of DatasetColumn objects from the IDataReader using a method defined in Kusto.Cloud.Data.ExtendedDataReader named ToEnumerable:

            using (var client = storageClientFactory.CreateCslQueryProvider(new Kusto.Data.KustoConnectionStringBuilder(connectionDetails!.ClusterUrl)))
            {
                var schemaQuery = KustoSchemaQueryBuilder.GetKustoSchemaQuery(connectionDetails!.EntityName);
                var clientRequestProperties = new ClientRequestProperties() { ClientRequestId = Guid.NewGuid().ToString() };
                var queryTask = client.ExecuteQueryAsync(connectionDetails.DatabaseName, schemaQuery, clientRequestProperties);
                using (var reader = await queryTask.ConfigureAwait(false))
                {
                    using (reader)
                    {
                        return reader.ToEnumerable<DatasetColumn>().ToArray();
                    }
                }
            }

Hoping that I will get an array of DatasetColumn objects. I do in fact get a list of DatasetObjects, the number of objects in the list corresponds to the number of results that I am expecting but all the objects have all the fields set to the default values (nulls for strings and 0 for ints).

What am I doing wrong and how do I get this method to return properly initialized objects? Am I misunderstanding the point of this extension method?

Later edit: I am adding a minimal program to reproduce the issue

using Kusto.Cloud.Platform.Data;
using Kusto.Data;
using Kusto.Data.Net.Client;
using Newtonsoft.Json;

namespace ConsoleApp1
{
    class DatasetColumn
    {
        public string? ColumnName { get; set; }
        public int ColumnOrdinal { get; set; }
        public string? DataType { get; set; }
        public string? ColumnType { get; set; }
    }

    internal class Program
    {
        static void Main(string[] args)
        {
            var sb = new KustoConnectionStringBuilder("https://help.kusto.windows.net/Samples; Fed=true; Accept=true");
            using (var client = KustoClientFactory.CreateCslQueryProvider(sb))
            {
                using (var result = client.ExecuteQuery("StormEvents | getschema"))
                {
                    var cols = result.ToEnumerable<DatasetColumn>().ToArray();
                    Console.WriteLine(JsonConvert.SerializeObject(cols));
                }
            }
        }
    }
}

Solution

  • the underlying implementation for the extension method of the DataReader that your code is using, and that is provided as part of the client library, doesn't currently support properties or private fields.

    You could either change the properties in the class DatasetColumn to fields, or write your own implementation.

    e.g., replace this:

    public int ColumnOrdinal { get; set; }

    with this:

    public int ColumnOrdinal;