LINQ to SQL объединяет 3 таблицы и выбирает несколько столбцов, а также использует Sum - PullRequest
4 голосов
/ 19 августа 2010

У меня есть три таблицы Student, TimeSheet и TimeRecord.

Столбики Талбе:

  • Студент: StudentId, FirstName, LastName

  • Расписание: TimeSheetId, StudentId, IsActive

  • TimeRecord: TimeRecordId, TimeSheetId, BonusHour (тип int), CreationDate

Таблица отношений:

  • Ученик 1: N TimeSheet (FK StudentId)
  • Расписание 1: N TimeRecord (FK TimeSheetId)

Данные об ученике:

StudentId, FirstName, LastName

  • 10, Макро, Джон
  • 11, Hiro, Edge
  • 12, Сара, Лимон

Данные образца расписания:

TimeSheetId, StudentId, IsActive

  • 187, 10, правда
  • 196, 11, True
  • 195, 12, True
  • 199, 10, False
  • 200, 12, Ложь

Пример данных TimeRecord:

TimeRecordId, TimeSheetId, BonusHour, IsValid, CreationDate

  • 1, 187, 1, Правда, 18.07.2010, 22:23:25
  • 2, 196, 2, True, 19.07.2010 14:23:25

  • 3, 187, 1, False, 01.08.2010 2: 5: 25 AM

  • 4, 187, 3, True, 9.09.2010 12:23:13

  • 5, 196, 0, правда, 20.07.2010 18:15:25

  • 6, 196, 2, правда, 18.09.2010 14:23:25

  • 7, 195, 3, False, 18.08.2010 14:23:25

  • 8, 199, 4, False, 18.07.2010 14:23:25

Я бы хотел получить общий BonusHour каждого студента, только Active TimeSheet имеет Valid BonousHour, который считается. Итак, результат будет примерно таким:

за июль месяц и т. Д. За любой месяц

  • У Hiro Edge 10 часов на июль 2010 года
  • У Сары Лем 8 часов на июль 2010 года
  • Макро Джон имеет 6 часов на июль 2010 года

Вот что я попробовал до сих пор:

 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)})}

Теперь проблема в том, как я могу получить "MonthYear" из "BournsHours". Потому что я хочу это так:

  • У Хиро Эджа 10 часов на июль 2010 года
  • У Сары Лем 8 часов на июль 2010 года
  • Макро Джон имеет 6 часов на июль 2010 года

  • Хиро Эдж имеет 0 часов на август 2010

  • У Сары Лем есть 3 часа на август 2010
  • Макро Джон имеет 2 часа на август 2010

и т. Д. За любой месяц.

Ответы [ 3 ]

3 голосов
/ 20 августа 2010

Вот рабочий запрос:

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 голосов
/ 19 августа 2010

Я знаю, что вы хотите код VB.NET, но у меня нет особого опыта в VB.NET, так что вот код C #. Вы можете конвертировать его с помощью конвертеров.

Предварительное условие: вы установили Entity Framework и, при необходимости, партнеров.

    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))
});

Редактировать: исправить ошибку ввода

2 голосов
/ 19 августа 2010

(некоторые 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 _
            }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...