【问题标题】:Comparing datatables / identify identical datatables比较数据表/识别相同的数据表
【发布时间】:2013-12-30 15:48:06
【问题描述】:

我正在使用 VB.net 和 mysql,我有一个函数可以用 mysql 内容填充数据表,然后将其(根据需要)发布到列表视图。此功能目前在一个每 5 秒激活一次的计时器上,不幸的是,这对我的软件的拖放功能造成了可怕的破坏。

解决方案:我决定在将内容填充到listview之后将活动数据表中的内容复制到另一个数据表进行比较,每次从mysql数据库中获取数据时都将其保存到数据表中并比较两者数据表 - 如果它们不相同,则软件应运行该函数,但是如果它们相同,则没有理由使用相同的确切数据更新列表视图。

    Public pendrun As New DataTable
    Public postrun As New DataTable

   Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        con.ConnectionString = "server=localhost;" _
& "user id=user;" _
& "password=password;" _
& "database=DMT"
    adptr = New MySqlDataAdapter("Select * from data", con)
    Try
        adptr.Fill(pendrun)
    Catch err As Exception
        Dim strError As String = "Exception: & err.ToString()"
    End Try
if pendrun <> postrun then
    ListView2.Items.Clear()
    pendrun.Clear()

' commands to add
' pendrun datatable information
' to listview

postrun = pendrun 'to transfer data to the holding datatable

end if

问题是

if pendrun <> postrun then

不是比较数据表的有效方法。 如何识别数据表是否相同(所有行和列都相同)

【问题讨论】:

    标签: mysql .net vb.net


    【解决方案1】:

    对于您定义的类型,没有对“相同”的内置理解。您需要编写该逻辑。

    本质上,您需要构建一个函数,该函数接受两个DataTables 作为输入,根据您定义的任何业务逻辑比较它们,并返回一个Boolean 指示它们是否通过该逻辑。像这样的:

    Function TablesAreEqual(ByVal firstTable As DataTable, ByVal secondTable As DataTable) As Boolean 
        ' Compare your tables, probably by looping through rows/values
        Return areEqual
    End Function
    

    然后您将在比较中使用该函数:

    If TablesAreEqual(pendrun, postrun) Then
    

    【讨论】:

      【解决方案2】:

      这是我为解决此问题而创建的结果代码 - 感谢 David 的指导

      Function TablesAreEqual(ByVal firstTable As DataTable, ByVal secondTable As DataTable) As Boolean
      dim db1 As String = ""
      dim db2 As String = ""
          For rown As Integer = 0 To firstTable.Rows.Count - 1
              For cown As Integer = 0 To firstTable.Columns.Count - 1
                  db1 = db1 & firstTable.Rows(rown).Item(cown)
              Next
          Next
          For rown As Integer = 0 To secondTable.Rows.Count - 1
              For cown As Integer = 0 To secondTable.Columns.Count - 1
                  db2 = db2 & secondTable.Rows(rown).Item(cown)
              Next
          Next
          Return db1 = db2
      
       End Function
      

      【讨论】:

      • 效率太低了。如果第一行和第一列不匹配,为什么要建立每一行和每一列?字符串是不可变的 - db1 = db1 & 效率非常低。为什么不从我在回答中建议的测试行数开始。如果没有排序,您可以拥有相同的行但顺序不同。如果您要写出全部​​内容,那么为什么不按照 Milani 的建议使用 WriteXml?
      • 正如我所说,我正在从 mysql 数据库中提取 - 在我的情况下,我使用的是 order 命令,所以事实上,如果订单发生变化,这将是一件大事,值得更新 listview -任何需要解决的更改 - 我正在使用我已经知道如何做的代码来寻找适用于我的应用程序的解决方案,我宁愿构建我的整个字符串,在我的场景中永远不会超过大约 2500 个字符,而不是添加搜索每一行的额外过程,我还开发了没有互联网连接的解决方案 - 从未见过你的帖子
      • 搜索每一行的附加程序是什么?您现在拥有的代码可以访问每一列和每一行。您现在拥有的代码进行权益比较。你可以用比现在更少的代码行来做到这一点。而且你的问题陈述中没有排序。
      【解决方案3】:

      如果您想使用您的 pendrun 和 postrun 数据表 尝试序列化“writeXml”数据表并进行比较。

      无论如何,我建议您考虑一种不同的方法,而不是使用轮询计时器。

      【讨论】:

        【解决方案4】:

        如果新数据没有改变,为什么不加入逻辑以不获取新数据。
        不知道 MySQL 但 MSSQL 有 Notification 和 TimeStamp

        列应仅随架构更改而更改。
        首先比较计数,如果不一样肯定有变化。
        如果计数相同,则循环遍历列并进行比较。
        一旦一个不比较然后完成立即​​返回false。

        在行上也是一样的。第一个测试行数。
        之后需要逐行逐列比较。
        请记住对 select 语句进行排序,以便您可以捕获乱序的行。
        再一次,只要一个人不比较就停止并返回假。

        正确的代码比您答案中的代码少
        我的插入是 C#

        Function TablesAreEqual(ByVal firstTable As DataTable, ByVal secondTable As DataTable) As Boolean
            if(firstTable.Rows.Count != secondTable.Rows.Count) return false;
            if(firstTable.Columns.Count != secondTable.Columns.Count) return false;
            For rown As Integer = 0 To firstTable.Rows.Count - 1
                For cown As Integer = 0 To firstTable.Columns.Count - 1
                    if (firstTable.Rows(rown).Item(cown) != secondTable.Rows(rown).Item(cown)) return false;
                Next
            Next
            return true;   
         End Function
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-07-04
          • 2016-01-15
          • 1970-01-01
          • 1970-01-01
          • 2016-02-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多