【问题标题】:Load collection except another collection using linq使用 linq 加载除另一个集合之外的集合
【发布时间】:2011-10-28 20:12:41
【问题描述】:

我有这个搜索方法:

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

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

我试着这样写:

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

Except 只能处理 Int、Guid、...等数据类型是个例外。

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    • 我使用了你的类并像这样使用它: context.Employees.Where(x => x.EmployeeName.Contains(keyword) && x.EmployeeTypeId == EmployeeTypeId).Except(Employees,new EmployeeComparer ()).Take(count).ToList();但我收到此错误:LINQ to Entities 无法识别方法 'System.Linq.IQueryable1[ManUp.Data.Employee] Except[Employee](System.Linq.IQueryable1[ManUp.Data.Employee], System.Collections.Generic.IEnumerable1[Data.Employee], System.Collections.Generic.IEqualityComparer1[Data.Employee])'方法,并且该方法不能翻译成商店表达式。
    • Amr ElGarhy:我明白了。在此之前,您需要 .AsEnumerable() 从数据库中提取结果。如果你想在数据库中完成这项工作,你应该使用连接来代替。
    • 是的,一开始我想做join,但我不是linq方面的专家,所以不会写,你能举个例子吗?
    【解决方案2】:

    如果您乐于检索所有数据并然后执行“例外”,那相对容易:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-05
      • 2013-12-21
      • 1970-01-01
      • 1970-01-01
      • 2019-02-05
      • 1970-01-01
      • 2017-07-18
      相关资源
      最近更新 更多