【问题标题】:iEnumrable vs IQueryable in linq working issuelinq 工作问题中的 iEnumerable 与 IQueryable
【发布时间】:2020-10-13 17:13:27
【问题描述】:

我是使用 linq 的初学者,我在使用 IEnumerable 时遇到此代码的问题,它返回数据,但使用 IQueryable 时却没有,我不知道为什么,还有另一个问题,使用 IEnumerable 时它如何返回不使用 ToList() 等函数的数据。

 public IQueryable<TempDTO> GetAllWorkers()
        {
            var query = (from q in _context.X
                         select new TempDTO
                         {
                             id=q.id,
                             .
                             .
                             .

                             Machines = GetMachinesListById(q.Id)
                         });
            return query;
        }
        private IEnumerable<Temp2DTO> GetMachinesListById(int? id){ // return query with machines}
        


这是我的 api

public IActionResult GetAllWorkers()
        {
            var result = _Repo.GetAllWorkers().Where(// condition);
            return Ok(result);
        }

提前致谢。

【问题讨论】:

  • 我认为这篇文章很好地解释了这两个接口之间的区别以及如何有效地使用它们。 stackoverflow.com/questions/2876616/…
  • 当我使用 IEnumerable 时 -- 究竟在哪里/如何?请发布有效的代码和无效的代码。
  • return query with machines 代码是我们需要查看才能正确回答您的问题的代码。

标签: asp.net entity-framework linq asp.net-core entity-framework-core


【解决方案1】:

我的理解是IQueryable 或多或少是对查询本身的引用,并且在查询运行之前(例如,通过调用.ToList().ToArray()),它不会被数据填充.

在您的情况下,您可以通过调用“.ToList()”来确保您的 IQueryable 在您的 API 控制器方法中执行:

var result = _Repo.GetAllWorkers().Where(condition).ToList();
return Ok(result);

【讨论】:

  • 感谢您的回答,但是当我使用 IEnumerable 时它如何工作并在不使用 ToList() 的情况下返回数据?
  • IEnumerable 立即执行“SELECT”并将结果存储在内存中,过滤(在您的 .Where() 中)在客户端完成。 IQueryable 在执行前通过在查询中添加 WHERE 子句在服务器上进行过滤。
  • 这篇文章展示了每个生成的实际 SQL。 c-sharpcorner.com/UploadFile/a20beb/…
  • @ChrisBrenberg - 否。IEnumerable&lt;T&gt; 使用与 IQueryable&lt;T&gt; 相同的惰性求值。它不会立即执行。两者都在您迭代集合时执行,即使用.ToList()
  • @ChrisBrenberg - 那篇文章很糟糕,有许多误导性和明显错误的陈述。
【解决方案2】:

我认为 @A-A-ron 在评论中给了你一个explanation

因为你在linq中使用了自定义方法GetMachinesListById,如果你使用IQueryablegetMachinesListById方法在sql端将无法识别,所以会出现异常。

正是因为它们的不同,当你使用IEnumerable时,所有当前对象都会在当前客户端执行,所以GetMachinesListById方法可以被识别并执行

看看Client vs. Server Evaluation

如果要使用 IQueryable,需要在 _context.X 中添加 .ToList()。

 public IQueryable<TempDTO> GetAllWorkers()
        {
            var query = (from q in _context.X.ToList()
                         select new TempDTO
                         {
                             id=q.id,
                             .
                             .
                             .

                             Machines = GetMachinesListById(q.Id)
                         });
            return query;
        }

还有一个问题,当使用 IEnumerable 时,它​​如何返回数据而不 使用 ToList() 等函数。

对于这个问题,IEnumerable 和 ToList 是two different types。如果要显示 ToList 的样式,只能在 Where 后面添加 ToList 方法,如下:

var result = _Repo.GetAllWorkers().Where(condition).ToList();

【讨论】:

    猜你喜欢
    • 2022-08-18
    • 1970-01-01
    • 1970-01-01
    • 2020-04-28
    • 2011-06-09
    • 1970-01-01
    • 1970-01-01
    • 2014-11-09
    • 1970-01-01
    相关资源
    最近更新 更多