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

时间:2013-06-17 10:28:44

标签: c# linq linq-to-entities

今天在使用LINQ时,我认为LINQ to实体不支持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记录
    • 和Concat他们与之前的设置
    • 并检查EmployeeID是否属于它的一部分,
    • 在X记录集中找到匹配的EmployeeId时中断循环。

2 个答案:

答案 0 :(得分:0)

您不应按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)

答案 1 :(得分: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)