【问题标题】:Is indexing on an IQueryable possible without converting to List?是否可以在不转换为 List 的情况下对 IQueryable 进行索引?
【发布时间】:2020-01-04 00:56:45
【问题描述】:

我有一个 Razor Pages Web 应用程序,其中我的 onget 方法有一个 LINQ 查询,可以找到不超过 5 条记录的集合(我的源是我创建的非常大的 SQL 视图):

IQueryable<int> ShipmentQtys = _MyContext
    .MaxShipmentEntries
    .Where(m => m.PartNo == currentPart)
    .Select(m => m.ShipQty);

它很快,但问题是我需要索引结果。我知道我需要改用 .ToList() ,但这会大大减慢我的加载时间,我假设是因为我的视野很大,所以我被困在如何解决这个问题上。

我需要对它进行索引,以便在我在应用程序中定义的 5 个字段中显示每条记录(最多 5 条)。一篇文章建议使用 .ElementAt,但 LINQ 不支持。

ShipQtyField1 = ShipmentQtys[0];
ShipQtyField2 = ShipmentQtys[1];
//etc.

有没有其他方法可以索引 IQueryable(或 IEnumerable),或者在我的情况下完全可以替代索引?

【问题讨论】:

  • .Take(5).ToList() ?这总是有点慢,因为只有当您开始枚举您实际执行(或编译+执行)查询的值时。但是是的,还有其他方法可以使用可查询或可枚举。
  • 或者,如果您说您的查询只能返回五个结果,并且第二次运行它仍然很慢(即在 EF 缓存了查询计划之后),那么我会检查一下您的查询实际上在 SQL 中运行得很快,例如您是否为 partNo 列编制了索引? SSMS 中的执行计划是什么样的 - 是否有表扫描?
  • 当您通过索引而不是先ToList()ing 然后使用索引访问记录时,您期望会发生什么?你认为这样会更快吗?
  • OK:那是因为在您放入 ToList 之前,您实际上并没有运行数据库查询。

标签: c# linq asp.net-core razor-pages


【解决方案1】:

您可以使用选择重载访问索引

  var tmp = new <yourtype>[i];
  ShipmentQtys.Select((x,i) => tmp[i] = x);

和ToArray一样,只是为了演示;

或者你可以枚举 IEnumerable

  var e = ShipmentQtys.GetEnumerator();
  if (e.MoveNext())
     ShipQtyField1 = e.Current;
  if (e.MoveNext())
     ShipQtyField2 = e.Current;

对于您的专用变量,我会推荐后一个版本。

但是没有办法随机访问,只能连续访问。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-30
    • 2016-02-20
    • 2017-06-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-08
    • 1970-01-01
    相关资源
    最近更新 更多