我正在创建一个安全跟踪HR应用程序,我正在尝试使用LINQ来返回每个安全事件类型的每个月的丢失小时数。相关的实体/表格列是:
[safety_incident]:
[incident_id]
[incident_date]
[incident_type]
[facility_id]
[safety_hours]:
[safety_hours_id]
[incident_id]
[safety_hours_date]
[lost_hours]
safety_incident和safety_hours之间的关系是0..n,其中safe_hours注意到特定日期的事件丢失了几个小时。我试图为事件类型和月份的每个组合返回一个记录/对象,超过一年(不一定都在同一日历年),其中丢失的小时数大于0.没有一年的边界或限制在设施上,我从SQL得到了我需要的东西:
SELECT (datepart(year,safety_hours_date) * 100 + datepart(month,safety_hours_date)),
inc.incident_type, sum(sh.lost_hours)
FROM [hr].[safety_hours] sh
INNER JOIN [hr].safety_incident inc ON sh.incident_id = inc.incident_id
GROUP BY (datepart(year,safety_hours_date) * 100 + datepart(month,safety_hours_date)),
inc.incident_type
HAVING sum(sh.lost_hours) > 0
ORDER BY (datepart(year,safety_hours_date) * 100 + datepart(month,safety_hours_date)),
inc.incident_type
我最接近已接受的LINQ查询是:
var monthInjuryHours =
from sh in _context.safety_hours
where sh.safety_hours_date >= firstMonth && sh.safety_hours_date < monthAfterLast && sh.lost_hours > 0
join inc in _context.safety_incident on sh.incident_id equals (inc.incident_id) into most
from m in most
where (facID == 0 || m.facility_id == facID)
group m by new
{
m.incident_type,
month = new DateTime(sh.safety_hours_date.Year, sh.safety_hours_date.Month, 1)
} into g
select new
{
injury = g.Key.incident_type,
month = g.Key.month,
hours = g.Sum(h => h.lost_hours) // ERROR, can't access lost_hours
};
不幸的是,我无法在“小时”行中指定lost_hours,或者在safe_hours的任何属性中,只有“_”之后才会出现safety_incident的属性。非常感谢任何帮助,谢谢...
编辑:我能够重新排列查询以切换两个表的顺序并得到一些运行的东西:
var monthInjuryHours =
from inc in _context.safety_incident
where (facID == 0 || inc.facility_id == facID) && inc.incident_date < monthAfterLast
join sh in _context.safety_hours on inc.incident_id equals (sh.incident_id) into most
from m in most
where m.safety_hours_date >= firstMonth && m.safety_hours_date < monthAfterLast
&& m.lost_hours > 0
group m by new
{
// Note new aliases
inc.incident_type,
month = new DateTime(m.safety_hours_date.Year, m.safety_hours_date.Month, 1)
} into g
select new
{
injury = g.Key.incident_type,
month = g.Key.month,
hours = g.Sum(h => h.lost_hours)
};
但是当我尝试使用foreach迭代它时,指向“in”关键字的NotSupportedException告诉我“在LINQ to Entities中只支持无参数构造函数和初始值设定项”。我发誓我已经有其他查询返回了匿名类型的集合,但无论如何......
答案 0 :(得分:0)
嗯,现在,答案是&#34; F(orget)LINQ&#34;。感谢Yuck对this topic的鼓舞人心的回答,Where()之后的ToList()允许此语法准确获取我之后的结果:
var monthInjuryHours = _context.safety_incident.Join(_context.safety_hours,
inc => inc.incident_id, sh => sh.incident_id, (inc, sh) => new { Inc = inc, Hours = sh })
.Where(j => j.Hours.lost_hours > 0 && (facID == 0 || j.Inc.facility_id == facID)
&& j.Inc.incident_date < monthAfterLast
&& j.Hours.safety_hours_date >= firstMonth
&& j.Hours.safety_hours_date < monthAfterLast).ToList() //Fixes things
.GroupBy(x => new { Month = new DateTime(x.Hours.safety_hours_date.Year,
x.Hours.safety_hours_date.Month, 1), x.Inc.incident_type })
.Select(g => new { g.Key.Month, g.Key.incident_type,
LostHours = g.Sum(x => x.Hours.lost_hours) })
.OrderBy(h => h.Month).ThenBy(h => h.incident_type);
我知道这不是最漂亮或最简单的例子,但我希望它有助于某人。