【问题标题】:LINQ to SQL join 3 tables and select multiple columns and also using SumLINQ to SQL 连接 3 个表并选择多个列并使用 Sum
【发布时间】:2010-08-19 15:08:53
【问题描述】:

我有三个表 Student、TimeSheet 和 TimeRecord。

Talbe 列:

  • 学生:StudentId,名字, 姓氏

  • TimeSheet:TimeSheetId、StudentId、IsActive

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

表关系:

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

学生样本数据:

学生 ID、名字、姓氏

  • 10,宏,约翰
  • 11, 希罗, 边缘
  • 12,莎拉,柠檬

时间表样本数据:

TimeSheetId、StudentId、IsActive

  • 187、10、真
  • 196、11、真
  • 195、12、真
  • 199, 10 , 错误
  • 200 , 12 , 假

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 , 2010 年 7 月 18 日下午 2:23:25

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

7 月份,以此类推任何月份

  • Hiro Edge 2010 年 7 月有 10 小时
  • Sarah Lem 2010 年 7 月有 8 小时的工作时间
  • Macro John 在 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 小时的工作时间
  • Macro John 在 2010 年 7 月有 6 小时的工作时间

  • Hiro Edge 的 2010 年 8 月为 0 小时

  • Sarah Lem 2010 年 8 月有 3 小时的工作时间
  • Macro John 在 2010 年 8 月有 2 小时的时间

任何月份的等等。

【问题讨论】:

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


    【解决方案1】:

    这是有效的查询:

    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
    

    【讨论】:

      【解决方案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))
      });
      

      编辑:修复输入错误

      【讨论】:

        【解决方案3】:

        (为清楚起见,删除了一些 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´s?它在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 _
                    }
        

        【讨论】:

        • 只修改一个小缺陷(从TimeRecordIdTimeSheetId
        • TimeSheet 有 TimeSheetId 作为 PK 所以,它是独一无二的。 StudentId、TimeRecordId 也是唯一的。
        • 好的,但是同一个学生可以有多个时间表,TimeSheet中的StudentId是唯一的吗?代码有效吗?另外,请参阅我回答中的最后一句话。
        • 请在问题中查看我的更新。是的,表格有关系。我只计算有效的 BonousHour 并且具有 Active TimeSheet。
        • 现在试试我的代码 - 再说一次,我不能 100% 确定它的有效 VB.net 代码
        猜你喜欢
        • 2011-04-20
        • 1970-01-01
        • 2012-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-28
        相关资源
        最近更新 更多