2017-01-24 3 views
0

вопрос я уже просил System.NotSupportedException - Cannot compare elements of type 'System.Linq.IQueryableNull проверка в Linq запрос

был ответ с ответом https://stackoverflow.com/a/41822351/2004251

метод в приведенном выше вопрос был модифицирован из ниже

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

Этот метод работает ожидается.

Мой вопрос: если null проверка работает в этом методе, почему она не работает, когда входной параметр преобразуется в IEnumerable<int>

+0

Я не эксперт SQL, но это мое предположение. В этом случае он видит, что одно значение «int?» Равно null, которое имеет эквивалент SQL. В указанном вопросе вы проверяете, является ли вся коллекция нулевой, что не так просто преобразовать в инструкцию SQL. – Abion47

+0

Какой _input параметр_ изменен на 'IEnumerable ', officeID? Это будет совершенно другой запрос. –

+0

@TimSchmelter Да, 'int? officeID' был изменен на 'IEnumerable officeIDs' – gvk

ответ

0

В первом случае ваш тип является IEnumerable, который не имеет никаких равных в SQL , Но второй случай является обнуляемым int, что SQL имеет точный тип для этого:

столбец с типом данных int и проверили позволяет аннулирует.

Так officeID == null можно преобразовать в выражение в SQL бок рамках объекта, но IEnumerable не тип, который может быть признан SQL, а с другой стороны, это значение является ссылкой на память. Как вы хотите проверить в SQL, что указанное место в вашей памяти приложения не указывает на нулевой объект.

0

С помощью коллекций используйте Contains() вместо этого, это вернет пользователей, если их идентификатор officeID находится в вашей коллекции.

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

Тогда вы можете совместить это с проверкой нулевой и выполнить другой запрос в зависимости от результата:

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(); 
Смежные вопросы