2017-01-24 2 views
0

Eine Frage, die ich fragte vorher System.NotSupportedException - Cannot compare elements of type 'System.Linq.IQueryableNull-Check in Linq-Abfrage

wurde mit der Antwort antwortete https://stackoverflow.com/a/41822351/2004251

Das Verfahren in der obigen Frage aus der unten

public List<User> GetActiveUsers(int? officeID, string roleID, string query) 
{ 
    return (from user in GetDBContext.User 
      join userRole in GetDBContext.UserRole 
       on user.UserID equals userRole.UserID 
      join userOffice in GetDBContext.UserAuthorizedOffice 
       on user.UserID equals userOffice.UserID 
      where user.IsActive == true && 
        user.UserTypeID == 1 && 
        userOffice.IsAuthorized && 
        userOffice.Office.IsActive && 
        (userOffice.OfficeID == officeID || officeID == null) && 
        string.Equals(userRole.RoleID, roleID) && 
        (user.FirstName + user.LastName).Contains(query) 
      select user).ToList(); 
} 

wurde modifiziert Diese Methode funktioniert wie erwartet.

Meine Frage: Wenn null Prüfung in dieser Methode funktioniert, warum es nicht funktioniert, wenn der Eingabeparameter zu IEnumerable<int>

+0

ich kein SQL-Experte bin, aber das ist meine Vermutung. In diesem Fall wird festgestellt, ob ein einzelner int? -Wert gleich null ist und eine SQL-Entsprechung hat. In der referenzierten Frage prüfen Sie, ob eine ganze Sammlung null ist, was nicht so einfach in eine SQL-Anweisung konvertiert werden kann. – Abion47

+0

Welcher _Eingangsparameter_ wird geändert in 'IEnumerable ', officeID? Das wäre eine völlig andere Abfrage. –

+0

@TimSchmelter Ja, 'int? officeID' wurde geändert in 'IEnumerable officeIDs' – gvk

Antwort

0

Im ersten Fall Ihre Art ein IEnumerable ist umgewandelt wird, die nicht gleich in SQL hat . Aber der zweite Fall ist ein Nullable-int dass SQL hat eine genaue Art dafür:

eine Spalte mit int Datentyp und geprüft nulls ermöglichen.

So officeID == null kann in SQL neben Entity Framework in einen Ausdruck umgewandelt werden, aber IEnumerable ist kein Typ, der von SQL und auf der anderen Seite erkannt werden kann, ist es ein Referenzwert im Speicher befindet. Wie möchten Sie in SQL einchecken, dass eine bestimmte Stelle in Ihrem Anwendungsspeicher nicht auf ein Nullobjekt zeigt.

0

Verwenden Sie bei Sammlungen stattdessen Contains(), damit Benutzer zurückgegeben werden, wenn sich ihre officeID in Ihrer Sammlung befindet.

public List<User> GetActiveUsers(IEnumerable<int> officeIDs, string roleID, string query) 
    { 
     return (from user in GetDBContext.User 
        join userRole in GetDBContext.UserRole 
        on user.UserID equals userRole.UserID 
        join userOffice in GetDBContext.UserAuthorizedOffice 
        on user.UserID equals userOffice.UserID 
        where user.IsActive == true && 
          user.UserTypeID == 1 && 
          userOffice.IsAuthorized && 
          userOffice.Office.IsActive && 
          officeIDs.Contains(userOffice.Office) 
          string.Equals(userRole.RoleID, roleID) && 
          (user.FirstName + user.LastName).Contains(query) 
        select user).ToList(); 
    } 

Dann können Sie diese mit einem Null-Check kombinieren und eine andere Abfrage auf das Ergebnis je ausführen:

return officeIDs != null 
        ? (from user in GetDBContext.User 
         join userRole in GetDBContext.UserRole 
         on user.UserID equals userRole.UserID 
         join userOffice in GetDBContext.UserAuthorizedOffice 
         on user.UserID equals userOffice.UserID 
         where user.IsActive == true && 
           user.UserTypeID == 1 && 
           userOffice.IsAuthorized && 
           userOffice.Office.IsActive && 
           officeIDs.Contains(userOffice.Office) 
           string.Equals(userRole.RoleID, roleID) && 
           (user.FirstName + user.LastName).Contains(query) 
         select user).ToList(); 
        : (from user in GetDBContext.User 
         join userRole in GetDBContext.UserRole 
         on user.UserID equals userRole.UserID 
         join userOffice in GetDBContext.UserAuthorizedOffice 
         on user.UserID equals userOffice.UserID 
         where user.IsActive == true && 
           user.UserTypeID == 1 && 
           userOffice.IsAuthorized && 
           userOffice.Office.IsActive && 
           string.Equals(userRole.RoleID, roleID) && 
           (user.FirstName + user.LastName).Contains(query) 
         select user).ToList(); 
Verwandte Themen