Linq to sql 如何编写使用先前记录值计算值的查询?

Linq to sql 如何编写使用先前记录值计算值的查询?,linq-to-sql,sql-server-ce,Linq To Sql,Sql Server Ce,我试图找出一种基于以前记录值计算值的最佳方法。我确信这是可能的,我就是想不出来 考虑一个具有StartTime和EndTime的表。除了这些值,还有两种不同类型的工资:OnDuty和off-duty OnDuty=从StartTime到EndTime之间的所有时间 下班时间:上一个结束时间和当前开始时间之间的所有时间 因此,要计算下班时间,我们必须取最后一条记录的结束时间,然后减去当前记录的开始时间 例子: 月工资=10美元/小时 下班工资=每小时2美元 条目1: 条目2: 条目3: 你看到图案

我试图找出一种基于以前记录值计算值的最佳方法。我确信这是可能的,我就是想不出来

考虑一个具有
StartTime
EndTime
的表。除了这些值,还有两种不同类型的工资:
OnDuty
off-duty

OnDuty=从
StartTime
EndTime
之间的所有时间

下班时间:上一个
结束时间
和当前
开始时间
之间的所有时间

因此,要计算
下班时间
,我们必须取最后一条记录的
结束时间
,然后减去当前记录的
开始时间

例子: 月工资=10美元/小时
  • 下班工资=每小时2美元
  • 条目1:

    条目2:

    条目3:

    你看到图案了吗

    Total Pay = $276 (Entry1.Pay + Entry2.Pay + Entry3.Pay)
    
    基本上,我在争论是否最好:

  • 将所有的负担都放在数据库上,以计算每一详细信息行的此值,或用每一行存储上一条记录的结束时间(即PreviousEndTime?)
  • 我更喜欢选项1。但是,我甚至不知道如何在不首先创建查找查询的情况下实现这一点(注意:我使用的是SqlCE)。我非常依赖LinqToSql,我关心使用Linq的性能,因为可能有数十万条这些“输入”记录需要计算,以便为每个员工提供一个单独的
    TotalPay
    。在每个细节行上执行该查找将是痛苦的

    另一方面,我觉得使用“PreviousEndTime”字段方法需要进行大量维护。用户可以返回并更改
    结束时间
    ,而更新下一个记录的
    上一个结束时间
    的想法对我来说听起来像是一种攻击


    想法?思想?解决方案?:)

    我强烈建议选择“让数据库承担计算每个细节行的此值的所有负担”这就是数据库(及其查询语言)的用途。

    在Oracle中,您将使用超前和滞后

    在SQL Server中,可能有一些变通方法,例如,请参见:


    但是,不确定SQL Server CE是否支持此选项。

    我强烈建议选择“将所有负担都放在数据库上,以便为每个详细信息行计算此值”这就是数据库(及其查询语言)的用途。

    在Oracle中,您将使用超前和滞后

    在SQL Server中,可能有一些变通方法,例如,请参见:


    但是,不确定SQL Server CE是否支持此操作。

    不需要存储前一行的结束时间。您可以使用排名函数计算与前一行的差异,然后执行自联接。

    无需存储前一行的结束时间。您可以使用排名函数计算与前几行的差异,然后执行自联接。

    回答:为了向大家介绍这方面的最新情况,我采用了不同的方法

    因为我使用的是SQL CE,它不支持视图或超前/滞后函数,所以我决定在表中添加一个新的
    PreviousEndTime
    列。这是我所能找到的唯一一种优雅的方式,它允许我轻松地查询
    员工
    的总计计算。这不是我喜欢的解决方案,但它对我来说很好

    这种方法的唯一缺点是,当用户在任何记录上更新其
    EndTime
    时,我必须快速查找以找到下一条记录并更新
    PreviousEndTime
    值,以确保查询时我的计算返回正确的值

    下面是我现在所做工作的一个快速伪代码片段:

    public decimal GetTotalPay(Employee employee) {
       return (from row in _timeSheet.GetDetailRows(employee.Id)
          select ((row.StartTime - row.PreviousEndTime) * employee.OffDutyWage) +
                 ((row.EndTime - row.StartTime) * employee.OnDutyWage)).Sum();
    }
    

    感谢所有的反馈。

    回答:为了向大家介绍这方面的最新情况,我采用了不同的方法

    因为我使用的是SQL CE,它不支持视图或超前/滞后函数,所以我决定在表中添加一个新的
    PreviousEndTime
    列。这是我所能找到的唯一一种优雅的方式,它允许我轻松地查询
    员工
    的总计计算。这不是我喜欢的解决方案,但它对我来说很好

    这种方法的唯一缺点是,当用户在任何记录上更新其
    EndTime
    时,我必须快速查找以找到下一条记录并更新
    PreviousEndTime
    值,以确保查询时我的计算返回正确的值

    下面是我现在所做工作的一个快速伪代码片段:

    public decimal GetTotalPay(Employee employee) {
       return (from row in _timeSheet.GetDetailRows(employee.Id)
          select ((row.StartTime - row.PreviousEndTime) * employee.OffDutyWage) +
                 ((row.EndTime - row.StartTime) * employee.OnDutyWage)).Sum();
    }
    

    谢谢您的反馈。

    哪个数据库?如果你有分析函数,你会得到以前的和其他好东西。“注意:我使用的是SqlCE”>>不幸的是,SqlCE不支持这些函数。谢谢。哪个数据库?如果你有分析函数,你会得到以前的和其他好东西。“注意:我使用的是SqlCE”>>不幸的是,SqlCE不支持这些函数。谢谢,谢谢你的回复。我认为SqlCE不支持Row_Number()函数。我可能不得不从另一个角度来看待我的设计,或者将逻辑转移到应用程序中。再次感谢,谢谢你的回复。我认为SqlCE不支持Row_Number()函数。我可能不得不从另一个角度来看待我的设计,或者将逻辑转移到应用程序中。再次感谢。我同意DB是为此而设计的。我担心的是,我使用LinqToSql的方法可能会使每行自引用同级行成为代价高昂的例行程序。我可能应该做一些基准测试,看看情况是否如此。不过,谢谢你的回复!它为我指明了正确的方向。我同意DB是为此而设计的。我所关心的是,我使用LinqToSql的方法
    Total Pay = $276 (Entry1.Pay + Entry2.Pay + Entry3.Pay)
    
    public decimal GetTotalPay(Employee employee) {
       return (from row in _timeSheet.GetDetailRows(employee.Id)
          select ((row.StartTime - row.PreviousEndTime) * employee.OffDutyWage) +
                 ((row.EndTime - row.StartTime) * employee.OnDutyWage)).Sum();
    }