0

有没有办法在不使用 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 等)。有没有办法可以从数据集本身获取格式的Duration总数?HH:MM我不想再次从数据库中查询来获取SUM. Duration我已经在这里发布了这个问题,但解决方案是使用我不想使用的 LINQ 查询。

4

2 回答 2

0

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

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

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

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

要从滴答声中获取 TimeSpan 的字符串表示形式:

/*
[-][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
于 2012-07-18T16:55:36.357 回答
0

我很好奇你为什么不想使用 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);
于 2012-07-18T16:53:23.440 回答