使用linq加载除另一个集合之外的集合

时间:2011-08-17 11:09:17

标签: c# linq entity-framework linq-to-sql ef-code-first

我有这种搜索方法:

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 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分:6)

如果您很乐意检索所有数据并然后执行“除外”,那就相对容易了:

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