У меня есть следующий код С#:
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), но это не нравится.
На самом деле, мой опыт заключался в том, что Oracle decimal неправильно преобразовывает в С# Int, при использовании OracleDataReaders мне нужно получить значение как десятичное число и преобразовать его в Int. Некоторые новые версии ODAC, похоже, исправили части этой проблемы.
выглядит как "% Down" - десятичное значение. В этом случае вы должны использовать:
AvgPercDown = grp.Average(r => r.Field<decimal>("% Down")),