Async - DataReader HasRows, но reader.Read () не работает - PullRequest
0 голосов
/ 07 мая 2018

Я посмотрел на десятки потоков, которые сейчас пытаются найти решение, но, похоже, у меня есть все на месте в соответствии с документацией Microsoft здесь (https://msdn.microsoft.com/en-us/library/1a674khd(v=vs.110).aspx) и согласно SO-темам, которые я видел. Любыепонимание было бы очень полезно.

Когда я запускаю приведенный ниже код, я не получаю данные из DataReader на reader.Read (). HasRows показывает True, но данные не читаются. Когда "while (reader.Read)()) "ударил, пропускает следующий раздел, указывая (я полагаю), что в считывателе нет данных. Когда я запускаю тестовый запрос, который просто по сути" SELECT Top 1 * from tableName ", я получаю результаты, поэтомуЯ считаю, что мой код правильно отформатирован для получения данных из считывателя.

Обратите внимание, я не показываю все данные для краткости ... SQL-запрос правильный, так как я скопировал из проверкиокно во время выполнения непосредственно в SSMS с параметрами, и значения возвращаются правильно. Оператор switch в последнем разделе урезан для экономии места. Класс DataHolder простосписок пары других классов (например, «Type1»), чтобы подготовить данные для последующей загрузки.

static async Task<DataHolder> DataBuilder(string type)
    {
        var constr = ConfigurationManager.ConnectionStrings["BS-CW"].ConnectionString;
        var start = new DateTime(DateTime.Now.AddMonths(-1).Year, DateTime.Now.AddMonths(-1).Month, 1); 
        var end = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).AddMilliseconds(-1); //getting all the data for the previous month
        var holder = new DataHolder();

        using (SqlConnection con = new SqlConnection(constr))
        using (SqlCommand cmd = new SqlCommand(Query(type), con))
        {
            // Query(type) does produce the correct SQL query, as tested in SSMS
            cmd.CommandTimeout = 1800; //30 min timeout
            cmd.Parameters.AddWithValue("@startdate", start);
            cmd.Parameters.AddWithValue("@enddate", end);

            con.Open();

            IAsyncResult result = cmd.BeginExecuteReader();

            var count = 0;
            var totalCount = 0;
            while (!result.IsCompleted)
            {
                if (count < 60)
                {
                    count++;
                    Console.Write(".");
                    System.Threading.Thread.Sleep(1000);
                }
                else
                {
                    count = 0;
                    totalCount++;
                    Console.WriteLine($"{totalCount} minute(s) waited...");
                }
            }

            using (SqlDataReader reader = cmd.EndExecuteReader(result))
            {
                holder = AddData(type, reader);
            }
        }
        return holder;
    }

static DataHolder AddData(string type, SqlDataReader reader)
    {
        var holder = new DataHolder();

        switch (type)
        {
            case "type1":
                while (reader.Read()) // FAILS HERE == NO DATA IN READER??
                {
                    var data = new Type1()
                    {
                        Date = Convert.ToDateTime(reader["Date"]),
                        DeviceId = Convert.ToInt64(reader["DeviceId"]),
                        Value = Convert.ToInt32(reader["Type1"])
                    };
                    holder.Type1List.Add(data);
                }
                break;
           default:
             break;
        }
    return holder;
}

SQL-запрос:

SELECT 
    cast(scantime as date) as [Date]
    ,d.deviceid as [DeviceId]
    ,CASE WHEN AVG([cpu_usage]) IS NULL THEN 0 ELSE AVG([cpu_usage]) END as [CPU]
FROM 
    [ods_10_ds1].[dbo].[datacpu_detailed] [data]
    join task t on [data].taskid = t.taskid
    join device d on t.deviceid = d.deviceid
    join customer c on d.customerid = c.customerid
where
    cast(scantime as date) >= @startdate
    and cast(scantime as date) <= @enddate
    and deviceclassid = 106
    and enabled = 1
    and d.deviceid in (1433949,9667189)
group by 
    cast(scantime as date), d.deviceid
order by
    cast(scantime as date), d.deviceid
...