Ottieni totale di una colonna dal set di dati in formato orario (HH: MM) utilizzando C # senza utilizzare Linq

C’è un modo per ottenere il totale di una colonna da un set di dati senza utilizzare una query LINQ?

CREATE procedure St_Proc_GetUserReportforCurrentDayTask @userID int as Begin set NoCount on; DECLARE @TODAY DATE SET @TODAY = CONVERT(VARCHAR(10), GETDATE(), 111) select CONVERT(VARCHAR,production.CalendarDate,101) + RIGHT (CONVERT(VARCHAR,production.CalendarDate , 100 ) ,7) as Date, RegionAndProjectInfo.RegionProjectName as Region , County.CountyName as County, WorkType.WorkTypeName as WorkType, Task.TaskName as Task, Production.VolumeProcessed as 'Volumes Processed', Production.TimeSpent as 'Duration' from Production inner join RegionAndProjectInfo on RegionAndProjectInfo.RegionProjectID=Production.RegionProjectID inner join County on County.CountyID=Production.CountyID inner join WorkType on WorkType.WorkTypeID=Production.WorkTypeID inner join Task on Task.TaskID=Production.TaskID where [email protected] and CalendarDate >= @TODAY End 

Dalla procedura memorizzata sopra, sto riempiendo un set di dati. Successivamente, collego questo Dataset a una vista a griglia. Nel set di dati, la colonna Duration contiene dati in formato HH: MM (esempio: 01:00, 12:45, 02:59, ecc.). C’è un modo per ottenere il totale di Duration nel formato HH:MM dal set di dati stesso? Non voglio eseguire nuovamente una query dal database per ottenere la SUM della Duration . Avevo già postato questa domanda Qui ma la soluzione era usare una query LINQ, che non voglio usare.

Sono curioso di sapere perché non vuoi usare Linq, ma sto divagando …

Ecco una versione non-linq-y che utilizza i loop:

 double total = 0; foreach(DataRow r in dataSet.Tables[0].Rows) { var DurHour = r["Duration"].ToString().Split(':')[0]; var DurMinute = r["Duration"].ToString().Split(':')[1]; TimeSpan ts = new TimeSpan(int.Parse(DurHour), int.Parse(DurMinute), 0); total += ts.TotalMinutes; } Console.WriteLine("Total time in minutes: {0}", total); 

È ansible utilizzare il metodo DataTable.Compute per fare somme, tuttavia, non saprà come gestire la durata come HH: MM. Dovresti fornire un’altra colonna in SELECT che converta HH: MM in un tipo numerico, quindi riconvertirla in HH: MM nel codice dopo la sum.

Se è ansible modificare lo schema del database, memorizzerei la durata come tick in una colonna int o bigint. Questo consente di convertire facilmente in TimeSpan sul lato .NET. Consente inoltre di eseguire più facilmente somme e controlli di intervallo in SQL. Se è necessario essere in grado di convertire TimeSpans in e da tick in SQL, è ansible utilizzare le funzioni seguenti che ho scritto. Ho dovuto inserire alcuni caratteri di sottolineatura casuale (_) per ottenere la risposta da inviare. (Per qualche ragione risparmiare tempo senza di loro.) Dovranno essere rimossi affinché il codice funzioni. Mi dispiace per quello

Per ottenere le zecche da una rappresentazione in formato stringa di una stringa temporale:

 /* [-][d.]hh:mm:ss[.fffffff] "-" A minus sign, which indicates a negative time interval. No sign is included for a positive time span. "d" The number of days in the time interval. This element is omitted if the time interval is less than one day. "hh" The number of hours in the time interval, ranging from 0 to 23. "mm" The number of minutes in the time interval, ranging from 0 to 59. "ss" The number of seconds in the time interval, ranging from 0 to 59. "fffffff" Fractional seconds in the time interval. This element is omitted if the time interval does not include fractional seconds. If present, fractional seconds are always expressed using seven decimal digits. */ CREATE FUNCTION [dbo].[ParseTimeSpanString] ( @timespan varchar(26) ) RETURNS INT AS BEGIN DECLARE @hourStart int DECLARE @minuteStart int DECLARE @secondStart int DECLARE @ticks bigint SET @hourStart = CHAR INDEX('.', @timeSpan) + 1 SET @minuteStart = CHAR INDEX(':', @timeSpan) + 1 SET @secondStart = CHAR INDEX(':', @timespan, @minuteStart) + 1 SET @ticks = 0 IF (@hourStart < @minuteStart) BEGIN SET @ticks = CON_VERT(int, LEFT(@timespan, @hourstart - 2)) * 864000000000 END ELSE BEGIN SET @hourStart = 1 END SET @ticks = @ticks + CON_VERT(int, SUBSTRING(@timespan, @hourStart, @minuteStart - @hourStart - 1)) * 36000000000 SET @ticks = @ticks + CON_VERT(int, SUBSTRING(@timespan, @minuteStart, @secondStart - @minuteStart - 1)) * 600000000 SET @ticks = @ticks + CON_VERT(decimal(9,7), SUBSTRING(@timespan, @secondStart, LEN(@timeSpan) - @secondStart)) * 10000000.0 RETURN @ticks END GO 

Per ottenere una rappresentazione di stringa di un TimeSpan dalle zecche:

 /* [-][d.]hh:mm:ss[.fffffff] "-" A minus sign, which indicates a negative time interval. No sign is included for a positive time span. "d" The number of days in the time interval. This element is omitted if the time interval is less than one day. "hh" The number of hours in the time interval, ranging from 0 to 23. "mm" The number of minutes in the time interval, ranging from 0 to 59. "ss" The number of seconds in the time interval, ranging from 0 to 59. "fffffff" Fractional seconds in the time interval. This element is omitted if the time interval does not include fractional seconds. If present, fractional seconds are always expressed using seven decimal digits. */ CREATE FUNCTION [dbo].[GetTimeSpanString] ( @ticks bigint ) RETURNS varchar(26) AS BEGIN DECL_ARE @timeSpanString varchar(26) IF @ticks < 0 BEGIN SET @timeSpanString = '-' END ELSE BEGIN SET @timeSpanString = '' END SET @ticks = ABS(@ticks) -- Days SET @timeSpanString = @timeSpanString + CON_VERT(varchar(26), FLOOR(@ticks / 864000000000.0)) + '.' SET @ticks = @ticks % 864000000000 -- Hours SET @timeSpanString = @timeSpanString + CON_VERT(varchar(26), FLOOR(@ticks / 36000000000.0)) + ':' SET @ticks = @ticks % 36000000000 -- Minutes SET @timeSpanString = @timeSpanString + CON_VERT(varchar(26), FLOOR(@ticks / 600000000.0)) + ':' SET @ticks = @ticks % 600000000 --Seconds DECLARE @seconds decimal(9,7) SET @seconds = @ticks / 10000000.0 SET @timeSpanString = @timeSpanString + CON_VERT(varchar(26), @seconds) RETURN @timeSpanString END GO