InvalidCastException Ошибка, вызванная строкой БД?

1

У меня есть следующий код С#:

private DataSet GetSummaryData(DataSet ds)
{
    DataSet dsSum = new DataSet();
    DataTable dtSum = new DataTable();


    DataTable dataTable = ds.Tables[0];

    if (dataTable != null)
    {
        if (dataTable.Rows.Count > 0)
        {
            if (dataTable.Columns.Count > 1)
            {
                dtSum.Columns.Add("Line Number", typeof(int));
                dtSum.Columns.Add("Throughput", typeof(int));
                dtSum.Columns.Add("Lost Time", typeof(int));
                dtSum.Columns.Add("Pounds Made", typeof(int));
                dtSum.Columns.Add("Pounds Lost", typeof(int));
                dtSum.Columns.Add("Yearly Potential", typeof(int));

                //Getting the Subtotal of PoundsMade based on the Line Number column
                //C# linq query
                var query = from row in dataTable.AsEnumerable()
                            group row by row.Field<int>("Linenumber") into grp
                            orderby grp.Key
                            select new
                            {
                                Linenumber = grp.Key,
                                TotalPoundsMade = grp.Sum(r => r.Field<int>("Pounds Made")),
                                AvgThroughput = grp.Average(r => r.Field<int>("Throughput")),
                                TotalLostTime = grp.Sum(r => r.Field<int>("Lost Time")),
                                AvgPercDown = grp.Average(r => r.Field<int>("% Down")),
                                TotalPoundsLost = grp.Sum(r => r.Field<int>("Pounds Lost")),
                                TotalYearlyPotential = grp.Sum(r => r.Field<int>("Yearly Potential")),
                            };

                foreach (var grp in query)
                {
                    dtSum.Rows.Add(grp.Linenumber, grp.TotalPoundsMade,grp.AvgThroughput,grp.TotalLostTime, 
                        grp.AvgPercDown, grp.TotalPoundsLost, grp.TotalYearlyPotential);
                    string strXML = null;
                        strXML = strXML + "<set name='" + grp.Linenumber + "' value='" + grp.TotalPoundsMade + "'/>";

                }

            }
        }
    }
    dsSum.Tables.Add(dtSum);
    return dsSum;
}

Этот код, как вы можете видеть, использует Linq для доступа к моей базе данных. SQL:

SELECT 
    PDT.LineNumber, 
    SUM(prdt.PoundsMade) as 'Pounds Made',
    CAST(ROUND(SUM(CAST(prdt.PoundsMade as DECIMAL))/ (MIN(LSA.AvailableHRS) - SUM(PDT.DownTimeHrs)),0,0) as int) 
as 'Throughput',
    SUM(PDT.DownTimeHrs) as 'Lost Time',
    Str(ROUND(CAST(SUM(PDT.DownTimeHrs) as DECIMAL)/CAST(MIN(LSA.AvailableHRS) as DECIMAL) * 100,0), 3,0) + '%' 
as '% Down', 
    CAST((ROUND(SUM(CAST(prdt.PoundsMade as DECIMAL))/ (MIN(LSA.AvailableHRS) - SUM(PDT.DownTimeHrs)),0,0))  * 
(SUM(PDT.DownTimeHrs)) as int) as 'Pounds Lost',
    CAST(ROUND(SUM(CAST(prdt.PoundsMade as DECIMAL))/ (MIN(LSA.AvailableHRS) - SUM(PDT.DownTimeHrs)),0,0) as int) * 
24 * 365  as 'Yearly Potential' 

FROM  
    rpt_Line_Shift_ProdDownTime AS PDT
    LEFT OUTER JOIN rpt_Line_Shift_Prod AS Prdt  
    ON  PDT.LineNumber = Prdt.LineNumber
    and PDT.ShiftNumber = Prdt.ShiftNumber 
    and PDT.WorkDate = Prdt.WorkDate 
    INNER JOIN rpt_Line_Shift_AvailableHrs AS LSA
    ON  PDT.LineNumber = LSA.LineNumber 
    and PDT.ShiftNumber = LSA.ShiftNumber
WHERE 
    PDT.WorkDate BETWEEN @p_From_Date and @p_Through_Date 
GROUP BY  
    PDT.LineNumber, PDT.ShiftNumber 
ORDER BY 
    PDT.LineNumber, PDT.ShiftNumber 

Похоже, что зависание состоит в том, что строка% Down не выполняется корректно. Это десятичный тип в SQL, и имеет смысл, что поэтому он должен быть спрятан для ввода int в С#. К сожалению, когда я запускаю программу, я получаю сообщение "InvalidCastException". Обратите внимание, что если я прокомментирую следующие фрагменты С#:

Msgstr "Среднее значение (r =

код "работает". Конечно, это не проблема./пожимание плечами

Есть предположения? Как я могу это исправить? Я попытался отличить строку% Down (в коде С#) как нечто отличное от int (например, double), но это не нравится.

Теги:
linq
sql-server-2012
visual-studio-2012

2 ответа

1
Лучший ответ

На самом деле, мой опыт заключался в том, что Oracle decimal неправильно преобразовывает в С# Int, при использовании OracleDataReaders мне нужно получить значение как десятичное число и преобразовать его в Int. Некоторые новые версии ODAC, похоже, исправили части этой проблемы.

  • 0
    Да, я смог исправить это, явно приведя поле «% Down» в файле .SQL. Таким образом, он выполняет расчет, а затем преобразует в int. Не самое элегантное решение, но оно дает мне результаты, которые мне нужны.
  • 0
    да, я расширил OracleDataReader для преобразования десятичных чисел в различные типы чисел в C #. Но я согласен, нам это не нужно.
Показать ещё 1 комментарий
0

выглядит как "% Down" - десятичное значение. В этом случае вы должны использовать:

AvgPercDown = grp.Average(r => r.Field<decimal>("% Down")),
  • 0
    Я действительно попробовал это, и ошибка все еще появляется. Я даже попытался сделать следующее утверждение: «AvgPercDown = grp.Average (r => (r.IsNull («% Down »)? 0: r.Field <decimal> («% Down »)))». Это, конечно, заботилось о любых возможных нулевых значениях. Я думал, что возможные нулевые значения могут быть проблемой. (И это была другая ошибка, которую я получал.) Однако, это не заканчивало тем, что исправляло это.
  • 0
    Какое именно сообщение об ошибке вы получите, когда попробуете мое предложение?
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню