簡體   English   中英

LINQ join,group by,sum

[英]LINQ join, group by, sum

我正在創建一個安全跟蹤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,或者安全_hours的任何屬性,只有在“h”之后才會出現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中只支持無參數構造函數和初始值設定項”。 我發誓我有其他查詢返回匿名類型的集合,但無論如何......

好吧,現在,答案是“F(orget)LINQ”。 感謝Yuck這個主題的鼓舞人心的回答,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);

我知道這不是最漂亮或最簡單的例子,但我希望它可以幫助某人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM