如何实现Linq to Entities IQueryable TakeWhile()功能

本文关键字:Entities IQueryable TakeWhile 功能 to Linq 实现 何实现 | 更新日期: 2023-09-27 18:18:53

今天在使用LINQ时,我了解到LINQ对实体不支持TakeWhile(),是否有任何有效的方法来实现这样的功能?我的用例如下-

我有一个Employee实体,并且我已经按名称对实体进行了排序,现在我想从这个IQueryable中获取记录,直到时间(EmployeeID = 123)

像这样-

IQueryable<Employee> employees = ObjectContext.Employees
          .OrderBy(a => a.Name)
          .TakeWhile(a => a.EmployeeId != 123)

但是在上面的代码中,Linq to Entities不支持TakeWhile,所以它会抛出一个错误。


我正在尝试下面的方法,如果有人有更好更有效的方法,请告诉我:

  • 获取第一个X记录,
  • 检查所需的EmployeeId是否是其中的一部分,
    • 如果没有,则获取下一组X记录
    • 并将它们与前一组
    • 连接
    • 并检查EmployeeID是否是其中的一部分,
    • 当在X记录集中找到匹配的EmployeeId时打破循环。

如何实现Linq to Entities IQueryable TakeWhile()功能

你不应该按Name排序,而应该按Id排序。也许,这会有所帮助:

// eager loading of employees, which name is less or equal, than stored name:
ObjectContext.Employees.Where(a => a.Name.CompareTo(storedName) < 0 || a.Name.CompareTo(storedName) == 0)
// lazy loading the rest of employees:
ObjectContext.Employees.Where(a => a.Name.CompareTo(storedName) > 0)

在SQL中没有等效的TakeWhile(),所以您必须在内存中执行该步骤。在添加没有SQL等效物的过滤器之前,您可以通过将IQueryable<>转换为IEnumerable<>来强制执行SQL。

var employees = ObjectContext.Employees
      .OrderBy(a => a.Name)
      .AsEnumerable()  // filters after this point will be done in memory on each record
      .TakeWhile(a => a.EmployeeId != 123)