LINQ to SQL连接3个表并选择多个列并使用Sum

时间:2010-08-19 15:08:54

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

我有三个表Student,TimeSheet和TimeRecord。

Talbe专栏:

  • 学生:StudentId,FirstName, 名字

  • TimeSheet:TimeSheetId,StudentId,IsActive

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

表关系:

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

学生样本数据:

StudentId,FirstName,LastName

  • 10,Macro,John
  • 11,Hiro,Edge
  • 12,Sarah,Lemon

TimeSheet示例数据:

TimeSheetId,StudentId,IsActive

  • 187,10,True
  • 196,11,True
  • 195,12,True
  • 199,10,False
  • 200,12,False

TimeRecord示例数据:

TimeRecordId,TimeSheetId,BonusHour,IsValid,CreationDate

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

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

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

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

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

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

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

我想获得每个学生的总BonusHour,只有Active TimeSheet有有效的BonousHour才算数。因此,结果将类似于以下内容:

七月份,以及任何一个月等等

  • Hiro Edge 2010年7月10小时
  • Sarah Lem 2010年7月有8小时
  • 宏约翰在2010年7月有6小时
  

这是我到目前为止所尝试的内容:

 Dim query = From ts In db.TimeSheet _ 
                 Join tr In db.TimeRecord On tr.TimeSheetId Equals ts.TimeSheetId _ 
                 Group By ts.StudentId, tr.TimeSheetId Into TotalTime = Sum(BonusHour) 
                 Select StudentId, TimeSheetId, TotalTime 

我还不能正确连接三张桌子。到目前为止我只能加入两张桌子。我需要将Student表连接到查询以获取学生姓名。

非常感谢。

  

更新一个

Dim query = From st In db.Student Select New With { .stName = st.FirstName & " " & st.LastName, _ 
.BonusHours = (From ts In st.TimeSheets Join tr in db.TimeRecord On tr.TimeSheetId Equals ts.TimeSheetId _
                    Where ts.IsActive = True And tr.IsValid = True _
                    Group By key = New With {ts.TimeSheetId, .MonthYear = (tr.CreationDate.Value.Month & "/" & tr.CreationDate.Value.Year)} Into BonusHr = Sum(tr.BonusHour)})}

现在,问题在于如何从“BournsHours”中获取“MonthYear”。因为我想这样:

  • Hiro Edge 2010年7月10小时
  • Sarah Lem 2010年7月有8小时
  • 宏约翰在2010年7月有6小时

  • Hiro Edge 2010年8月的0小时

  • Sarah Lem 2010年8月有3小时
  • Macro John在2010年8月有2小时

等任何一个月。

3 个答案:

答案 0 :(得分:3)

这是工作查询:

Dim query = From ts In db.TimeSheets_
            Join tr In db.TimeRecords On tr.TimeSheetId Equals ts.TimeSheetId _
     Where ts.IsActive = True And tr.IsValid = True _
     Group By key = New With {ts.Student, .MonthYear = (tr.TimeOut.Value.Month & "/" & tr.TimeOut.Value.Year)} Into TotalHour = Sum(BonusHour) _
                     Select key.Student.StudentId, key.Student.AssignedId, key.MonthYear, TotalHour

答案 1 :(得分:2)

(为清楚起见,删除了一些C#和备选方案,请参阅历史记录)

C#到VB.Net(不知道这是否正确VB.Net):

Dim query = From st In db.StudentNew With { _
 st.FirstName, _
 st.LastName, _
 Key .BonusHours = (From ts In st.TimeSheets _ //Or st.TimeSheet
                    Where ts.IsActive _
                    From tr In ts.TimeRecords _ //Or ts.TimeRecord
                    Where tr.IsValid
                    Select tr.BonusHour).Sum() _
}

如果您在列上有unique,则应使用.Single而不是from。列上有哪些unique?它在TimeSheet中是唯一的吗?

如果使用外键设置关联,LINQ to SQL可以使这更容易。

根据您更新的代码

添加(我认为这实际上不是有效的代码):

Dim query = From st In db.Student
            Let pair = From ts In st.TimeSheets
                       Join tr In db.TimeRecord On tr.TimeSheetId Equals ts.TimeSheetId _
                       Where ts.IsActive = True And tr.IsValid = True _
                       Group By key = New With {
                           tr.CreationTime.Month,year/month - not sure how the syntax will be
                           tr.CreationTime.Year} Into BonusHr = Sum(tr.BonusHour)}
            From part In pair.BonusHr
            Select New With {
                .stName = st.FirstName & " " & st.LastName, _
                .BonusHours = part.BonusHours, _
                .YearMonth = key.Month + " " + key.Year _
            }

答案 2 :(得分:2)

我知道你想要VB.NET代码,但我在VB.NET中没有太多exp,所以这里是C#代码。您可以使用转换器进行转换。

先决条件:您已根据需要设置了实体框架和关联。

    var q = db.Students
              .Include("TimeSheet")
              .Include("TimeSheet.TimeRecord")
              .ToList();

    q.ForEach(i=>
{
  Console.WriteLine(string.Format("{0} {1}: {2} bonus hours",i.FirstName, i.LastName, i.Sum(ii => ii.BonusHour))
});

编辑:修复输入错误