2012-01-12 1 views
1

Я хочу получить список всех студентов, которые были на одном из двух событий. Вот моя функция, чтобы получить список посещаемости:Где Содержит два вызова функций

Private Function AttendanceList(ByVal Mode As AttendanceListLookupMode, ByVal AttendaceTypeID As Integer, ByVal EventID As Integer, ByVal EventOccurenceDate As Date) As IEnumerable(Of Integer) 
     'Get the attendance table for specified event 
     Dim resultSet = From a In db.tblAttendances 
         Where a.tblEventOccurence.EventID = EventID _ 
          And a.tblEventOccurence.EventOccurenceDate = EventOccurenceDate 

     'Apply mode filtering 
     Select Case Mode 
      Case AttendanceListLookupMode.AttendanceTypeIs 
       resultSet = resultSet.Where(Function(x) x.tblAttendanceType.AttendanceTypeID = AttendaceTypeID) 
      Case AttendanceListLookupMode.AttendanceTypeIsNot 
       resultSet = resultSet.Where(Function(x) x.tblAttendanceType.AttendanceTypeID <> AttendaceTypeID) 
     End Select 

     'Return the student records 
     Return resultSet.Select(Function(x) x.StudentID) 
    End Function 

    Private Enum AttendanceListLookupMode 
     AttendanceTypeIs 
     AttendanceTypeIsNot 
    End Enum 

Теперь я хочу использовать это в запросе, чтобы проверить, либо мероприятии приняли участие, как это:

'All students 
       Dim resultSet = From s In db.tblStudents 

       resultSet = resultSet.Where(Function(x) 
               AttendanceList(AttendanceListLookupMode.AttendanceTypeIsNot, 
                   CommonAttendanceTypeIDs.Absent, 
                   CommonEventIDs.Learning, 
                   ForDate).Contains(x.StudentID) 
               Or 
               AttendanceList(AttendanceListLookupMode.AttendanceTypeIsNot, 
                   CommonAttendanceTypeIDs.Absent, 
                   CommonEventIDs.Basketball, 
                   ForDate).Contains(x.StudentID) 
              End Function) 

Когда я пытаюсь скомпилировать это я получить эту ошибку:

Error 1 Overload resolution failed because no accessible 'Where' can be called with these arguments: 
Extension method 'Public Function Where(predicate As System.Linq.Expressions.Expression(Of System.Func(Of tblStudent, Integer, Boolean))) As System.Linq.IQueryable(Of tblStudent)' defined in 'System.Linq.Queryable': Nested function does not have a signature that is compatible with delegate 'System.Func(Of tblStudent, Integer, Boolean)'. 
Extension method 'Public Function Where(predicate As System.Linq.Expressions.Expression(Of System.Func(Of tblStudent, Boolean))) As System.Linq.IQueryable(Of tblStudent)' defined in 'System.Linq.Queryable'. 
Extension method 'Public Function Where(predicate As System.Func(Of tblStudent, Integer, Boolean)) As System.Collections.Generic.IEnumerable(Of tblStudent)' defined in 'System.Linq.Enumerable': Nested function does not have a signature that is compatible with delegate 'System.Func(Of tblStudent, Integer, Boolean)'. 
Extension method 'Public Function Where(predicate As System.Func(Of tblStudent, Boolean)) As System.Collections.Generic.IEnumerable(Of tblStudent)' defined in 'System.Linq.Enumerable'. 

ответ

1

у меня нет компилятора под руку, чтобы проверить, но это выглядит, как вы используете синтаксис лямбды в многострочном, но с указанием голого выражения. Компилятору это не понравится, он ожидает выражения, а не выражения. Два Синтаксисы отличаются следующим образом:

Dim singleLinelambda = Function(x) x + 1 

Dim multiLineLambda = Function(x) 
          Return x + 1 
         End Function 

Попробуйте вместо этого:

resultSet = resultSet.Where(Function(x) 
    Return AttendanceList(AttendanceListLookupMode.AttendanceTypeIsNot, 
     CommonAttendanceTypeIDs.Absent, 
     CommonEventIDs.Learning, 
     ForDate).Contains(x.StudentID) Or 
     AttendanceList(AttendanceListLookupMode.AttendanceTypeIsNot, 
     CommonAttendanceTypeIDs.Absent, 
     CommonEventIDs.Basketball, 
     ForDate).Contains(x.StudentID) 
    End Function) 

Лично я бы переместить тело лямбды в отдельный метод с параметрами. Это сделает код более читаемым, например.

Private Function MyPredicate(Mode As AttendanceListLookupMode, AttendaceTypeID As Integer, EventID1 As Integer, EventID2 As Integer, EventOccurenceDate As Date, StudentID As Integer) As Boolean 
    Return AttendanceList(Mode, 
     AttendaceTypeID, 
     EventID1, 
     EventOccurenceDate).Contains(StudentID) Or 
     AttendanceList(Mode, 
     AttendaceTypeID, 
     EventID2, 
     EventOccurenceDate).Contains(StudentID) 
End Function 

' Usage... 
resultSet = resultSet.Where(Function(x) MyPredicate(
    AttendanceListLookupMode.AttendanceTypeIsNot, 
    CommonAttendanceTypeIDs.Absent, 
    CommonEventIDs.Learning, 
    CommonEventIDs.Basketball, 
    ForDate, 
    x.StudentID)) 
+0

Он вообще не принимает заявление лямбда, я этого не осознавал. Я смог использовать символ продолжения строки VB _, чтобы сделать мой оператор lambda выражением lambda и теперь он компилируется. –

+0

Ааааа, вы используете VS2008, извините. В этом случае многострочный синтаксис лямбда недоступен, поэтому делать то, что вы сделали, лучше. :-) –

Смежные вопросы