簡體   English   中英

如何使用 MAX 將分組從 sql 轉換為 linq 查詢

[英]How to transform grouping with MAX from sql to linq query

我試圖將 sql 查詢轉換為 linq:

SELECT
    Table1.Id1,
    Table2.Id2,
    MAX(Table3.DateField) AS MaxDateField
FROM
    Table1 
INNER JOIN
    Table2 ON Table1.Id1 = Table2.FK1 
LEFT OUTER JOIN
    Table3 ON Table2.Id2 = Table3.FK2
GROUP BY 
    Table1.Id1, Table2.Id2

Table1/Table2 關系是一對多,Table2/Table3 也是一對多。

SQL 工作正常,表 1 和表 2 的每條記錄僅提供表 3 中的一條記錄。

對於 linq 我試過:

var query = from table1 in tables1
            join table2 in tables2 on table1.Id1 equals table2.FK1
            join table3 in tables3 on table2.Id2 equals table3.FK2 into JoinedTable3Table2
            from table3 in JoinedTable3Table2.DefaultIfEmpty()

            group new {
                 table3.MyDateField
            }
            by new  {
                 table1.Id1,
                 table2.Id2,
                 table3.MyDateField
            }
            into g    
            select new MyModel {
                 Field1 = g.Key.Id1,
                 Field2 = g.Key.Id2,
                 Field3 = g.Max(d => d.MyDateField)
            };

但這會為 Table1 和 Table2 中的每條記錄從 Table3 中返回 n 條記錄。

然后我嘗試了(正如 Svyatoslav Danyliv 建議的那樣):

var query = from table1 in tables1
            join table2 in tables2 on table1.Id1 equals table2.FK1
            join table3 in tables3 on table2.Id2 equals table3.FK2 into JoinedTable3Table2
            from table3 in JoinedTable3Table2.DefaultIfEmpty()

            group new {
                 table1.Id1,
                 table2.Id2
            }
            by new  {
                 table1.Id1,
                 table2.Id2,
                 table3.MyDateField
            }
            into g    
            select new MyModel {
                 Field1 = g.Key.Id1,
                 Field2 = g.Key.Id2,
                 Field3 = g.Max(d => d.MyDateField) 
            };

但后來我在Field3 = g.Max(d => d.MyDateField) (CS 1061:anonymous type) 得到一個錯誤

您在分組字段table3.MyDateField方面存在差異。 此外,如果您的 model 具有適當的導航屬性,則可以簡化您的查詢。

var query = from table1 in tables1
            from table2 in table1.Table2s 
            from table3 in table2.Table3s 

            group table3
            by new  {
                 table1.Id1,
                 table2.Id2
            }
            into g    
            select new MyModel {
                 Field1 = g.Key.Id1,
                 Field2 = g.Key.Id2,
                 Field3 = g.Max(d => d.MyDateField)
            };

如果您的 model 定義正確,則您實際上不需要在 LINQ 中進行連接。

看看這個查詢是否有效

var results = context.tables2.Select(row => new 
        { row.FK1, row.ID2, MaxDate = row.LinkedEntities.Max(e => e.MyDateField) }));

這將要求您將LinkedEntities定義為表 2 和表 3 之間 1-* 關系的導航屬性。

感謝 Badar 和 Danyliv 的幫助,我找到了一個可行的解決方案。

我需要提一下,我發布的示例是一個簡化版本。 我還需要通過“左外連接”將 table2 連接到第四個表(Table4),以便從 Table4 中獲取屬性(未設置導航屬性),但匹配鍵可用。

var query = from table1 in tables1
            join table2 in tables2 on table1.Id1 equals table2.FK1

            join table4 in tables4 on table2.Id2 equals table4.FK2 into JoinedTable4Table2
            from table4 in JoinedTable4Table2.DefaultIfEmpty()

            join table3 in tables3 on table2.Id2 equals table3.FK2 into JoinedTable3Table2
            from table3 in JoinedTable3Table2.DefaultIfEmpty()

            group table3 // needed to be changed
            by new {
                 table1.Id1,
                 table2.Id2,
                 table4.Id4,
                 // any other field, but no field from table3
                 // table3.MyDateField // had to be removed!!
            }
            into g    
            select new MyModel {
                 Field1 = g.Key.Id1,
                 Field2 = g.Key.Id2,
                 Field4 = g.Key.Id4,
                 Field3 = g.Max(d => d.MyDateField)
                 //... 
            };

暫無
暫無

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

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