【问题标题】:Unable to access items of an IQueryable<T> by index无法按索引访问 IQueryable<T> 的项目
【发布时间】:2023-03-05 10:01:01
【问题描述】:

我是 C# 新手。我正在尝试使用由 linq 查询生成的应该是列表(?)来在订购表格上构建表。其中一部分涉及引用该列表中的特定项目,如下所示:

using (CellOrderingDBEntities db = new CellOrderingDBEntities())
{
    var AccessoryItems = from AccessoryDescription in db.Accessories
                         join HardwareID in db.HardwareTypes
                             on AccessoryDescription.HardwareType equals HardwareID.HardwareID
                         where AccessoryDescription.DateRetired == null
                         select AccessoryDescription;

    List<Device> DevicesList = (List<Device>)Session["DevicesList"];

    Guid AccessoriesOrder = (from ServiceID in db.TypeOfServices
                                where ServiceID.ServiceType == "Accessories Order"
                                select ServiceID.ServiceID).FirstOrDefault();

    //This Int is used to build the accessories table
    int AccessoryRows = AccessoryItems.Count();

    if (SType == AccessoriesOrder)
    {
        for (int r = 0; r <= AccessoryRows; r++)
        {
            TableRow row = new TableRow();
            for (int c = 0; c < 3; c++)
            {
                TableCell cell = new TableCell();
                TextBox tb = new TextBox();
                int ai = 0;
                int ri = 0;

                tb.ID = "TextBoxRow_" + r + "Col_" + c;
                if (c == 0)
                {
                    cell.Controls.Add(tb);
                }
                else if (c == 1)
                {
                    cell.Text = AccessoryItems[ai];
                    ai++;
                }
            }
        }
    }

我被这个错误困住了:

无法使用 [] 将索引应用于“System.Linq.IQueryable”类型的表达式

我尝试将其转换为字符串列表,但由于我不明白为什么它不允许我按索引访问 IQueryable 的原因。

【问题讨论】:

  • 如果有人知道一个很好的资源来让我了解类型,我想这就是我没有得到的,因为我一直在努力解决这个问题,我会接受的。非常感谢!
  • 你可能会发现使用这个语法更容易:foreach (var ai in AccessoryItems) 而不是这个:for (int r = 0; r &lt;= AccessoryRows; r++),如果你不需要 r 来索引AccessoryItems以外的任何东西
  • 就良好的 LINQ 资源而言:下载 LINQPad (linqpad.net) 并使用它。 (我也可以推荐 J. & B. Albahari 的 C# 4.0/5.0 in a Nutshell btw。)此外,我建议您了解本地(参见 IEnumerable)和解释查询(参见 IQueryable) 和 LINQ 的延迟执行模式。一旦你理解了这些概念,事情就会变得更加清晰。
  • Linq 操作使用延迟执行,因此仅在您请求时才检索项目。通过索引访问一个项目也意味着首先阅读所有以前的项目,如果你不止一次这样做,这当然是非常低效的。如果您首先将项目加载到集合中(即通过将 .ToList().ToArray() 附加到查询末尾),然后您可以按索引访问您的项目。
  • 除了前面提到的 C# 4.0/5.0 in a Nutshell 和 LINQPad 建议之外,我还推荐 C# in Depth

标签: c# iqueryable


【解决方案1】:

您可以使用ElementAt 访问序列中特定点的元素。所以,替换:

cell.Text = AccessoryItems[ai];

cell.Text = AccessoryItems.ElementAt(ai) as String;

【讨论】:

  • 同样的问题。这只是得到这个错误。 :/ 无法将类型“Data.Accessory”隐式转换为“字符串”它是实体框架之外的数据类型。
  • 你可以使用 as 关键字将类型转换为字符串吗? (即 cell.Text = AccessoryItems.ElementAt(ai) as String;)注意:"the conversion isn't possible, as returns null instead of raising an exception" 所以你可能需要检查空值。
  • 我只是得到一个不同的错误。无法通过引用转换、装箱转换、拆箱转换、包装转换或空类型转换将类型“Data.Accessory”转换为“字符串”
  • 那是Accessory类的问题,Brad的回答还是正确的。如果你 override ToString method 在你的 Accessory 类中,你会修复转换错误。没有您的帮助,编译器无法自动将您的类转换为字符串。
【解决方案2】:

想通了:

                    var AccessoryItems = from AccessoryDescription in db.Accessories
                                     join HardwareID in db.HardwareTypes
                                     on AccessoryDescription.HardwareType equals HardwareID.HardwareID
                                     where AccessoryDescription.DateRetired == null
                                     select AccessoryDescription;

                List<Accessory> AIL = AccessoryItems.ToList();

这在 for 循环中:

cell.Text = (string) AIL[ai].AccessoryDescription;

而且它有效!

【讨论】:

  • 此查询未指定顺序,因此返回的项目未按任何定义的顺序。索引这样的集合并没有真正的意义。这意味着这里存在真正的设计缺陷;您可能根本不需要对查询结果进行索引。
  • 您能帮我解释一下这个缺陷的性质吗?一旦查询运行,当我遍历结果时,订单不应该改变,因为我不确定我需要具体的订单吗?非常感谢。
  • 如果您的目标只是遍历整个结果集,那么您根本不需要按索引访问项目。如果这是您的目标,您可以只使用 foreach 而不是 for 来访问所有项目。
  • 从我读到的内容中,我的理解是在构建表时不能使用 foreach 循环?也就是我看到的所有例子都说要用for循环吗?我最初实际上想使用 foreach 。 (感谢您帮助我理解这个@Servy!)
  • 酷。感谢您忍受我敢肯定的问题。我会看看我是否能弄清楚如何做到这一点。似乎是一种更好的方法来接近它。我如何给你代表,标记你的 cmets 有用等等...?
猜你喜欢
  • 1970-01-01
  • 2015-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-23
  • 2017-08-18
相关资源
最近更新 更多