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

Amr*_*rhy 3 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();
}
Run Code Online (Sandbox Code Playgroud)

我有另一个Employeees集合,比如"BadEmployeees",我想要的是使用相同的先前方法返回除"BadEmployeees"之外的所有Employeees.

我试着像这样写:

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

但它提供了一个例外,Except可以使用Int,Guid等数据类型...

Guf*_*ffa 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();
  }

}
Run Code Online (Sandbox Code Playgroud)

用法:

return
  context.Employeees
  .Where(x => x.EmployeeeName.Contains(keyword) && x.EmployeeeTypeId == employeeeTypeId)
  .Except(BadEmployeees, new EmployeeComparer())
  .Take(count)
  .ToList();
Run Code Online (Sandbox Code Playgroud)


Jon*_*eet 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();
Run Code Online (Sandbox Code Playgroud)

或者:

// 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();
Run Code Online (Sandbox Code Playgroud)