检查 ArrayList 是否包含 属性 等于特定值的对象

Check if ArrayList contains an object with a property that equals a specific value

所以我在 VB.net 中有一个应用程序从 table 中提取数据并将其插入到数组列表中以备后用。我想要做的是在将对象添加到数组列表之前,我想检查该数组列表以查看该对象是否存在,但我希望能够根据该对象的特定 属性 进行检查。

这是我所说的一个例子:

假设我从 table 中提取信息,其中包含以下列: 发票编号|收费日期|数量|总费用

我有一个 SQL 语句从 table 中提取信息,然后我使用数据 reader 来浏览信息。我的代码看起来有点像这样:

Dim dbobjM As New clsDbobjManual()
If dbobjM.Exec_SQL_DR("SELECT InvoiceNo, DateCharged, Quantity, TotalCharges From Invoices") =  0 Then
  If dbobjM.DataReader.HasRows Then
    Dim invoicelist As New ArrayList(5000)
    Dim invoiceno As String = String.Empty
    Do While dbobjM.DataReader.Read()
      invoicelist.Add(New Invoice(dbobjM.DataReader.GetInt32(0), dbobjM.DataReader.Value(1), dbobjM.DataReader.GetInt32(2), dbobjM.DataReader.GetFloat(3)))
    Loop
  End If
End if

(Exec_SQL_DR 是 clsDbobjManual class 中的一个函数,它首先检查以确保 SQL 语法正确,然后检查是否返回记录,否则它 returns一个错误)

基本上我想做的是在我将一个新对象添加到数组列表之前我想检查一个对象是否已经存在于列表中,其中 InvoiceNo 是一个特定的值,或者从 [=36 中提取的值=] 每次都确保没有重复。我希望列表中的每个 InvoiceNo 都有一个对象。

我正在寻找类似的东西:

If Not invoicelist.Contains(Object where InvoiceNo = dbobjM.DataReader.GetInt32(0)) Then
  invoicelist.Add
End If

但我似乎找不到我需要的东西,非常感谢任何帮助

您可以使用 linq select 符合您条件的对象。

Dim result = (From invoiceitem As Invoice
             In invoicelist 
             Where invoiceitem.InvoiceNo = dbobjM.DataReader.GetInt32(0)
             Select invoiceitem).ToList()

If Not result.Count > 0 Then
  invoicelist.Add(New Invoice(dbobjM.DataReader.GetInt32(0), dbobjM.DataReader.Value(1), dbobjM.DataReader.GetInt32(2), dbobjM.DataReader.GetFloat(3)))
End If 

没有必要使用过时的 ArrayList:List 会更好地为您服务。如果您需要原因,请参阅 ArrayList vs List<> in C# - 列表的优点也适用于 VB.NET。

没有看到你的 clsDbobjManual 或 Invoice 类,我最终编写了最少的代码来完成你想要的,这基本上是检查 invoices.Any(Function(i) i.InvoiceNo = inv.InvoiceNo),如果你可以这样做在清单(发票)中包含数据。

请注意,我假设已在数据库中使用了适当的数据类型 - 您应该使用 Decimal 类型作为金钱,否则您最终可能会出现严重的舍入错误,并且日期应存储为 DateTime, 不是作为字符串。

Imports System.Data.SqlClient

Module Module1

    Class Invoice
        Property InvoiceNo As Integer
        Property DateCharged As DateTime
        Property Quantity As Integer
        Property TotalCharges As Decimal

        Sub New()
            ' empty constructor
        End Sub

        Sub New(invoiceNo As Integer, dateCharged As DateTime, quantity As Integer, totalCharges As Decimal)
            Me.InvoiceNo = invoiceNo
            Me.DateCharged = dateCharged
            Me.Quantity = quantity
            Me.TotalCharges = totalCharges
        End Sub

    End Class

    Function LoadData() As List(Of Invoice)
        Dim invoices As New List(Of Invoice)
        Dim connStr As String = "your connection string"

        Dim sql = "SELECT InvoiceNo, DateCharged, Quantity, TotalCharges From Invoices"

        Using sqlConn As New SqlConnection(connStr)
            Using sqlCmd As New SqlCommand(sql, sqlConn)
                Dim reader As SqlDataReader = sqlCmd.ExecuteReader()

                While reader.Read()
                    Dim inv As New Invoice(reader.GetInt32(0), reader.GetDateTime(1), reader.GetInt32(2), reader.GetDecimal(3))

                    If Not (invoices.Any(Function(i) i.InvoiceNo = inv.InvoiceNo)) Then
                        invoices.Add(inv)
                    Else
                        ' there is a duplicate invoice number
                    End If

                End While

            End Using
        End Using

        Return invoices

    End Function


    Sub Main()
        Dim uniqueInvoices As List(Of Invoice) = LoadData()
        ' uniqueInvoices now contains the data
    End Sub

End Module

如果您有很多 个发票条目要处理,您可能最好编写一个SQL 查询来执行此操作。

如果您实际上只是想查找重复的发票编号,您可以使用 SQL

SELECT [InvoiceNo]
FROM testTable
GROUP BY [InvoiceNo]
HAVING COUNT([InvoiceNo]) > 1

最后,请确保您使用的是 Option Strict On,以免出现意外数据类型错误 - 它们会大大降低您的程序速度并导致错误结果。