Linq to SQL根据参数(daily、Monthly..)按日期段分组

本文关键字:Monthly 日期 daily SQL to 参数 Linq | 更新日期: 2023-09-27 18:25:06

我正在尝试创建一个返回Date分组结果的Linq-to-SQL查询。挑战在于根据可枚举参数(周期性)对每日/每周/每月/季度进行分组。下面,我当前的Linq到SQL查询:

var TotalGroupedInvoices = from c in entidades.InvoicesView
                     group c by (periodo == periodicity.Daily) ? c.InvoiceDate.Date :
                                      period == periodicity.Weekly?     c.InvoiceDate.Date.AddDays(-(double)c.InvoiceDate.DayOfWeek) :
                                      period == periodicity.Monthly? new DateTime(c.InvoiceDate.Year,c.InvoiceDate.Month ,1) :
                                      period == periodicity.Quarterly? new DateTime(c.InvoiceDate.Year, c.InvoiceDate.Month - (c.InvoiceDate.Month % 3) +1, 1) :
                                      period == periodicity.Anual ? new DateTime(c.InvoiceDate.Year, 1, 1) : inicio into Periods
                     select new
                     {
                         period = Periods.Key,
                         Total = Periodos.Sum(c => c.Total)
                     };

为了澄清,请查看季度期间代码片段:

period == periodicity.Quarterly? new DateTime(c.InvoiceDate.Year, c.InvoiceDate.Month - (c.InvoiceDate.Month % 3) +1, 1)

因此,对于进入第一季度的日期,如:2012年1月12日、2012年1月份15日或2012年3月20日,我将所有日期都分组在2012年1月下一季度,因此它可以按预期工作。

首先,我想知道查询效率。你对此怎么看?也许为了提高SQL Server的效率,最好将句点转换为整数,并在客户端上重新转换为日期句点,但我对此不确定。

另一方面,每周小组将每周的日期分组到每周的第一个星期日:

period == periodicity.Weekly? c.InvoiceDate.Date.AddDays(-(double)c.InvoiceDate.DayOfWeek)

但这对我来说是不正确的,因为我来自西班牙,星期一开始上班。我如何才能将这一点考虑在内来确定周组?

因此,总结:

  • 这个Linq-to-SQL查询效率如何
  • 如果不考虑周一到周日的几周,我怎么能每周按此分组

非常感谢!PD:对不起我的英语水平。

Linq to SQL根据参数(daily、Monthly..)按日期段分组

要回答第一部分,您并不真的想将枚举值传输到数据库中,并让它决定使用哪个代码分支。您拥有在本地做出决定的所有信息。

Expression<Func<InvoicesView, DateTime>> groupingExpr = c => c.InvoiceDate.Date;
if (period == periodicity.Weekly)
{
  groupingExpr = c => c.InvoiceDate.Date.AddDays(-(double)c.InvoiceDate.DayOfWeek);
}
else if (period == periodicity.Monthly)
{
  groupingExpr = c => new DateTime(c.InvoiceDate.Year,c.InvoiceDate.Month ,1);
}
else if (period == periodicity.Quarterly)
{
  groupingExpr = c => new DateTime(c.InvoiceDate.Year, c.InvoiceDate.Month - (c.InvoiceDate.Month % 3) +1, 1);
}
else if (period == periodicity.Anual
{
  groupingExpr = c => new DateTime(c.InvoiceDate.Year, 1, 1);
}

var TotalGroupedInvoices = entidades.InvoicesView 
  .GroupBy(groupingExpr)
  .Select(grouped => new {
    period = grouped.Key,
    Total = grouped.Sum(c => c.Total)   
  });

以下是我能做的最好的事情,将groupingExpr与查询理解语法相结合:

var TotalGroupedInvoices = from grouped in entidades.InvoicesView.GroupBy(groupingExpr)
  select new {
    period = grouped.Key,
    Total = grouped.Sum(c => c.Total)   
  };

要回答第二部分,只需要做一些"day"运算。您可以内联或作为单独的函数(例如扩展方法)执行此操作:

public static DateTime FirstDayOfWeek (this DateTime date)  
{  
  double offset = (date.DayOfWeek == DayOfWeek.Sunday) ? -6 : (DayOfWeek.Monday - date.DayOfWeek);  
  return date.AddDays(offset);  
}

然后在你的LINQ:

period == periodicity.Weekly ? c.InvoiceDate.FirstDayOfWeek

然而,考虑到您是从SQL中检索的,您可能只想查看那里的日期函数,例如DATEPART,并在查询

中返回它们