【问题标题】:How do I get a field of a datatable when I know column name and a row ID, without looping?当我知道列名和行 ID 时,如何在不循环的情况下获取数据表的字段?
【发布时间】:2013-12-06 06:14:31
【问题描述】:

当我知道列名和行 ID 时,如何在不循环的情况下获取数据表的字段?

例如;当地区 = 城市和产品 = 乐高积木时,我想要“总销售量”值。这是我长期以来一直在努力解决的问题,可能是因为我认为在 SQL 中,一直循环遍历所有内容似乎并不总是正确的方法。但是,如果我只是需要学习像 VB 开发人员一样思考并且总是循环从列表或表格中获取一些东西,请告诉我。

我有一系列比较两个数据表的断言,一个有一行,每个单元格都有一个命名列(来自 SSRS 生成的 XML),另一个数据表有一个区域中每个唯一值的一行(由SQL 查询)。

来自 SQL 的表(模型数据集):

Region  Prod  Total Sold
City    Legos   68
State   Legos   90
Nat.    Legos   200
City    ToyB    20
State   ToyB    30
Nat.    ToyB    40
City    ToyC    450
State   ToyC    600
Nat.    ToyC    900

来自 XML 的表(从 SSRS 返回的数据集):

City_Legos  State_Legos  Nat_Legos  City_ToyB  State_ToyB Nat_ToyB City_ToyC State_ToyC 
68          90           200          20           30     40       450        600

assert 语句中从基于 XML 的数据表中获取数据的部分很简单,因为只有一行(索引 0),我可以只命名我想要的列:

Dim xmlRow As DataRow = xmlDatatable.Rows(0)
Assert.AreEqual(“my SQL cell goes here”, xmlRow.Field(Of Integer)(“City_Legos”))

我可以为每个指定的列做一个断言。许多列不会被测试,它们有特定的名称,所以我不能简单地循环遍历这些列。那么我应该在“我的 SQL 单元格到这里”中输入什么来返回城市和乐高积木的总销售量?显然,在 SQL 中这很容易:SELECT TOP 1 Total_Sold WHERE Region = City and Prod = Legos。 我目前正在遍历 SQL 数据表并根据我的标准测试每个单元格,但是这个逻辑变得很大,因为我必须将每个单元格都包装在 If...Then 中,就像这样:

For Each m As DataRow In mySqlTable.Rows

If m.Field(Of String)("Prod") = "Legos" Then
    If m.Field(Of String)("Region") = "City" Then
        Assert.AreEqual(m.Field(Of Integer)("TotalSold"), xmlRow.Field(Of Integer)(“City_Legos”))
    End If
    If m.Field(Of String)("Region") = "State" Then
        Assert.AreEqual(m.Field(Of Integer)("TotalSold"), xmlRow.Field(Of Integer)(“State_Legos”))
    End If
    If m.Field(Of String)("Region") = "Nat" Then
        Assert.AreEqual(m.Field(Of Integer)("TotalSold"), xmlRow.Field(Of Integer)(“Nat_Legos”))
    End If
End If
Next

我希望我可以做一些类似选择、LINQ 或函数的事情? 像这样的东西会很好:

Dim result as Integer =  mySqlTable.Select.First(“Region = City and Prod = Legos“)

或者:

Assert.AreEqual(mySqlTable.Select.First(“Region = City and Prod = Legos“), xmlRow.Field(Of Integer)(“City_Legos”))

这是一个单元测试,所以我会一直知道 SSRS 返回的列名和字段名。

通过列名和行标识符获取单元格一直是我一直在努力解决的问题,所以希望我最终能解决这个问题。

谢谢!

【问题讨论】:

  • 如果你有一个元素列表并且你想选择满足某些条件的元素,你将不得不搜索这个列表(= 循环遍历它)直到找到你想要的。这是人类和计算机唯一可用的选项 :) VB.NET 有很多“快捷方式”来以非常概括的方式编写循环(例如:LINQ 查询),但无论如何这些都是循环。通常,当您说“无循环”时,您的意思是类似于 LINQ,但只是想明确这一点。此外,LINQ 不必比传统循环更有效(取决于具体情况)。
  • @varocarbas - 非常感谢。我认为答案可能是“你应该总是循环”。我通常会这样做,因为 SSRS 数据通常是表格的,但在这种情况下它是单向的。当然我仍然可以循环,但我仍然想找到单例值。谢谢,这有助于我对 VB 中处理数据的一般理解。
  • 与VB.NET无关;它与编程有关(以及……常识)。如果您有一个元素列表并且想知道您拥有的元素在哪个位置;你有两个选择:幸运的猜测(计算机不会这样做)或查看所有元素直到找到想要的元素。编程语言有很多“花哨的东西”这一事实无法掩盖现实:最后,一切都是循环和条件(循环遍历所有元素并检查是否......)。不知道这意味着您应该认真了解编程的基本知识。
  • ...如果你是程序员,你不能指望事情会一蹴而就(这是你应该构建的程序的用户;一个魔法信徒),你应该明白事情为什么会发生。如果您三思而后行,您就会明白,不检查列表中的元素,就没有明智的、不基于魔法的方法来查找列表中的元素位置 :) 无论如何......不客气.在这里提供帮助。
  • 谢谢,我很高兴知道何时需要了解一个重要概念。我以为我可以做一些类似 SQL 的事情,我从来不需要使用游标(循环)。无论后台是否有 SQL 循环,我都不必在 SQL 中编写循环。无论如何,接受的答案对我当前的项目很有用。再次感谢。

标签: vb.net datatable dataset datatables


【解决方案1】:

您可以使用数据表计算方法。将(“我的 SQL 单元格放在这里”替换为 CInt(mySqlTable.Compute("SUM([Total Sold])", "[Region] = 'City' and [Prod] = 'Legos'")) 这是假设行是唯一的并且没有空值。

【讨论】:

  • 嗯,这当然可以,谢谢!我试图找出一种不使用 SUM 的方法,而是使用 First() 之类的方法,以防万一有重复的行。但是,考虑到应该始终只有唯一的行,这目前很有效。
  • 那么,Compute 到底是什么?它是基于魔法还是基于循环?
  • 我以前每5个assert有13行循环代码,现在我有5个assert的5行代码,减少了8行代码。乘以我需要测试的 16 组,我只保存了 128 行代码。但是,很高兴知道它在内存中仍在循环。
  • @BClaydon 以及您认为 LINQ 的用途是什么?减少代码的大小(对于那些关心的人,而不是我自己)。但是,这不能让你认为现在事情变得更快了:无论如何循环都完成了,事情可能会更慢。如果您更喜欢此选项,那就太好了;但您的问题很明确:如果没有循环,您将无法分析任何集合。
猜你喜欢
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-05
  • 1970-01-01
  • 2016-12-15
  • 2013-05-04
  • 1970-01-01
相关资源
最近更新 更多