在不使用Linq的情况下,使用C#从时间格式(HH:MM)中获取数据集的总和

有没有办法在不使用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 Production.UserID=@userID and CalendarDate >= @TODAY End 

从上面的存储过程,我填写数据集。 之后,我将此数据集绑定到网格视图。 在数据集中,列Duration包含HH:MM格式的数据(例如 – 01:00,12:45,02:59等)。 有没有办法可以从数据集本身获得HH:MM格式的Duration总数? 我不想再从数据库中查询以获得DurationSUM 。 我已经发布了这个问题在这里,但解决方案是使用LINQ查询,我不想使用。

我很好奇为什么你不想使用Linq,但我离题了……

这是一个使用循环的un-linq-y版本:

 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); 

您可以使用DataTable.Compute方法来执行求和,但是,它不知道如何处理持续时间为HH:MM。 您需要在SELECT中提供另一个用于将HH:MM转换为数字类型的列,然后在求和后将其转换回代码中的HH:MM。

如果您可以更改数据库模式,我会将持续时间存储为int或bigint列中的刻度。 这样你就可以轻松地在.NET端转换为TimeSpan。 它还允许您更轻松地在SQL中执行求和和范围检查。 如果您需要能够在SQL中将TimeSpans转换为ticks,则可以使用我编写的下面的函数。 我必须插入一些随机的下划线(_)字符来获取我提交的答案。 (出于某种原因,在没有它们的情况下节省时间。)为了使代码工作,需要删除它们。 对于那个很抱歉。

要从时间字符串的字符串表示中获取刻度:

 /* [-][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 

要从ticks获取TimeSpan的字符串表示forms:

 /* [-][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