LINQ按月分组提问

我是LINQ to SQL的新手,我想知道如何在LINQ中实现这样的东西:

Month Hires Terminations Jan 5 7 Feb 8 8 Marc 8 5 

到目前为止我已经有了这个,我觉得它有问题,但我不确定:

 from term1 in HRSystemDB.Terminations group term1 by new { term1.TerminationDate.Month, term1.TerminationDate.Year } into grpTerm select new HiresVsTerminationsQuery { Date = Criteria.Period, TerminationsCount = grpTerm.Count(term => term.TerminationDate.Month == Criteria.Period.Value.Month), HiresCount = (from emp in HRSystemDB.Persons.OfType() group emp by new { emp.HireDate.Month, emp.HireDate.Year } into grpEmp select grpEmp).Count(e => e.Key.Month == Criteria.Period.Value.Month) }); 

提前致谢。

我不太确定Criteria.Period值在样本查询中的来源。

但是,我认为您正在尝试阅读所有可用月份的招聘和终止(然后您可以轻松过滤它)。 如果第一个表(终止)没有包含某个指定月份(例如5月)的任何记录,那么您的查询可能会出错。 然后不会使用“May”作为参数调用select子句,即使你在第二个表中有一些数据(代表Hires),那么你也无法找到它。

使用Concat方法可以很好地解决这个问题(参见MSDN示例)。 您可以选择所有的术语和所有雇员(进入某种类型的数据结构),然后按月对所有数据进行分组:

 var terms = from t in HRSystemDB.Terminations select new { Month = t.TerminationDate.Month, Year = term1.TerminationDate.Year, IsHire = false }; var hires = from emp in HRSystemDB.Persons.OfType() select new { Month = emp.HireDate.Month, Year = emp.HireDate.Year IsHire = true }; // Now we can merge the two inputs into one var summary = terms.Concat(hires); // And group the data using month or year var res = from s in summary group s by new { s.Year, s.Month } into g select new { Period = g.Key, Hires = g.Count(info => info.IsHire), Terminations = g.Count(info => !info.IsHire) } 

现在查看代码时,我很确定有一些更短的方法来编写它。 另一方面,这段代码应该是非常易读的,这是一个好处。 另请注意,我们将代码拆分为几个子查询并不重要。 由于LINQ to SQL的惰性评估,这应该作为单个查询执行。

我不知道它是否更短但你也可以尝试这个版本,看看它是否适用于你的服务器。 我不确切地知道这两个答案是如何变成SQL语句的。 根据您的索引等可能会更好。

 var terms = from t in Terminations group t by new {t.Month, t.Year} into g select new {g.Key, Count = g.Count()}; var hires = from p in Persons group p by new {p.Month, p.Year} into g select new {g.Key, Count = g.Count()}; var summary = from t in terms join h in hires on t.Key equals h.Key select new {t.Key.Month, t.Key.Year, Hires = h.Count, Terms = t.Count};