避免LINQ with Let关键字进行自循环

时间:2010-08-19 20:02:18

标签: c# vb.net linq linq-to-sql .net-3.5

我有三个表Student,TimeSheet和TimeRecord。

Talbe专栏:

  • 学生:StudentId,AssignedId,FirstName, 名字

  • TimeSheet:TimeSheetId,StudentId,IsArchive,IsComplete

  • TimeRecord:TimeRecordId,TimeSheetId,BonusHour(type int),CreationDate

表关系:

  • 学生1:N时间表(FK StudentId)
  • 时间表1:N TimeRecord(FK TimeSheetId)

学生样本数据:

StudentId,AssignedId,FirstName,LastName

  • 100,741,Macro,John
  • 101,742,Hiro,Edge
  • 102,743,莎拉,柠檬 和儿子在.. ..

TimeSheet示例数据:

TimeSheetId,StudentId,IsArchive,IsComplete

  • 187,100,True,False
  • 196,101,True,False
  • 195,102,True,False
  • 199,100,True,True
  • 200,102,True,True

TimeRecord示例数据:

TimeRecordId,TimeSheetId,BonusHour,CreationDate

  • 1,187,1 / 7/18/2010 10:23:25 PM
  • 2,196,2,7 / 19/2010 2:23:25 PM

  • 3,187,1,8 / 1/2010 2:5:25 AM

  • 4,187,3,8 / 9/2010 12:23:13 PM

  • 5,196,0,7 / 20/2010 6:15:25 PM

  • 6,196,2,9 / 18/2010 2:23:25 PM

  • 7,195,3,8 / 18/2010 2:23:25 PM

  • 8,199,4,7 / 18/2010 2:23:25 PM

实际上,我正试图获得每个学生的每月总奖金时数。

    Dim query = From s In db.Students _
                 Let pair = (From ts In db.TimeSheets _
          Join tr In db.TimeRecords On tr.TimeSheetId Equals ts.TimeSheetId _
    Where ts.IsArchive = False And ts.IsCompleted = False And tr.TimeOut IsNot Nothing _
    Group By key = New With {ts.StudentId, .MonthYear = (tr.CreationDate.Value.Month & "/" & tr.CreationDate.Value.Year)} Into TotalHour = Sum(tr.BonusHour)) _
                From part In pair _
                Select New With {.stId = s.AssignedId, .MonthYear = part.key.MonthYear, .TotalHour = part.TotalHour}

此查询循环“pair”元素并将其分配给每个学生。

AssignedId , MonthYear, TotalHour

- 741, 6/2010 , 5
- 742, 6/2010 , 5
- 743, 6/2010 , 5
- 744, 6/2010 , 5
- 745, 6/2010 , 5

- 741, 7/2010 , 8
- 742, 7/2010 , 8
- 743, 7/2010 , 8
- 744, 7/2010 , 8
- 745, 7/2010 , 8

等等。“pair”元素的最后结果。

所以,正确的结果应该是这样的:

- 741, 6/2010 , 5
- 742, 6/2010 , 8
- 743, 6/2010 , 9
- 744, 6/2010 , 10
- 745, 6/2010 , 15

或者像这样:

AssignedId,月/年例如:

AssignedId, 7/2010, 8/2010

 - 741 , 8hr, 2hr
 - 742, 3hr ,4hr
 - 743, 3hr, 1hr
 - and son on..

你能帮我纠正上面的查询吗?欢迎使用C#或VB.NET中的任何建议。  感谢。

2 个答案:

答案 0 :(得分:1)

我会考虑从TimeRecord本身开始,而不是从学生开始。只要您的Linq To Sql映射是正确的(并且关系已到位),您就已经拥有了一些有用的关系属性。这是我如何形成查询,尽管在移动到VB时可能需要进行一些更改。

var hours = from tr in db.TimeRecords
            where !tr.TimeSheet.IsArchive && !tr.TimeSheet.IsCompleted && tr.TimeOut != null
            group tr.BonusHour by
                new {
                        tr.TimeSheet.Student,
                        MonthYear = tr.CreationDate.Value.Month + "/" + tr.CreationDate.Value.Year
                    }
            into g
            select new {g.Key.Student.AssignedId, g.Key.MonthYear, TotalHour = g.Sum()};

如果您的模型不同,请告诉我,但这个想法对您有用。

答案 1 :(得分:0)

在顶层,您的查询由两个结果集组成:

  1. db.Students
  2. 对,由Let子句定义。
  3. 由于您在顶层有两个From子句(一个用于db.Students,一个用于对),没有JoinWhere子句将一个子句关联到另一个子句, LINQ构造了它们之间的交叉连接。

    我认为您希望Join第二个结果集(对)到第一个(db.Students),或以其他方式在顶级Where子句中指示它们的关联。