Загрузить коллекцию, кроме другой коллекции, используя linq - PullRequest
3 голосов
/ 17 августа 2011

У меня есть этот метод поиска:

public List<Employeees> AutoSuggestEmployeee(string keyword,
    long employeeeTypeId, int count)
{
    return context.Employeees.Where(
        x => x.EmployeeeName.Contains(keyword)
        && x.EmployeeeTypeId == employeeeTypeId)
    .Take(count).ToList();
}

У меня есть другая коллекция сотрудников, скажем "BadEmployeees", я хочу использовать тот же предыдущий метод, чтобы вернуть всех сотрудников, кроме "BadEmployeees".

Я пытался написать это так:

return context.Employeees.Where(
        x => x.EmployeeeName.Contains(keyword)
        && x.EmployeeeTypeId == employeeeTypeId)
    .Except(BadEmployeees).Take(count).ToList();

Но есть исключение, что Except может работать только с такими типами данных, как Int, Guid, ...

Ответы [ 2 ]

7 голосов
/ 17 августа 2011

Метод Except выполняет сравнение, поэтому он должен знать, как сравнивать объекты.Для простых типов существуют стандартные сравнения, но для сложных типов необходимо предоставить средство сравнения на равенство, которое сравнивает соответствующие данные в объекте.

Пример:

class EmployeeComparer : IEqualityComparer<Employeees> {

  public bool Equals(Employeees x, Employeees y) {
    return x.Id == y.Id;
  }

  public int GetHashCode(Employeees employee) {
    return employee.Id.GetHashCode();
  }

}

Использование:

return
  context.Employeees
  .Where(x => x.EmployeeeName.Contains(keyword) && x.EmployeeeTypeId == employeeeTypeId)
  .Except(BadEmployeees, new EmployeeComparer())
  .Take(count)
  .ToList();
6 голосов
/ 17 августа 2011

Если вы счастливы получить все данные и , тогда выполняет «кроме», это относительно просто:

return context.Employees
              .Where(x => x.EmployeeName.Contains(keyword)
                          && x.EmployeeTypeId == employeeeTypeId)
              // Limit the data *somewhat*
              .Take(count + BadEmployees.Count)
              // Do the rest of the query in-process
              .AsEnumerable()
              .Except(BadEmployees)
              .Take(count)
              .ToList();

В качестве альтернативы:

// I'm making some assumptions about property names here...
var badEmployeeIds = badEmployees.Select(x => x.EmployeeId)
                                 .ToList();

return context.Employees
              .Where(x => x.EmployeeName.Contains(keyword)
                          && x.EmployeeTypeId == employeeeTypeId)
                          && !badEmployeeIds.Contains(x.EmployeeId))
              .Take(count)
              .ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...