65.9K
CodeProject 正在变化。 阅读更多。
Home

VB 中的带 SelectDistinct 的 DataTable

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.44/5 (4投票s)

2007年10月4日

CPOL

4分钟阅读

viewsIcon

69121

downloadIcon

592

允许您对DataTable执行Distinct查询。

Screenshot - Demo_VB.gif

引言

VS.NET提供的ADO.NET对象允许您从数据库或其他源检索数据,并将其存储在称为DataSetDataTable的对象中。事实上,DataSetDataTable的集合。DataTable的一个常用方法是Select()。它允许开发人员对DataTable执行简单的过滤,并返回结果作为DataRow的集合。目前,没有办法对DataTable执行Distinct查询。我刚刚发现,在.NET中有一个执行Distinct查询的方法。DataView对象公开了一个名为ToTable()的方法。此方法需要一个布尔标志来确定是否Distinct以及您希望Distinct的字段。虽然此方法确实从DataTable返回Distinct行,但似乎它只能用于小型记录集。当用于包含40,000行的DataTable时,大约需要18秒。我估计对于一百行左右的数据来说,它会非常快。但是,如果您想对大型表进行Distinct,没有更好的方法。直到现在。

背景

我最近遇到了一个问题,服务器太慢,无法处理用户对大量返回数据的请求。我需要检索数据并在内存中完全操作数据,以减少访问SQL Server的次数。一个主要的障碍是我需要对我的DataTable应用Distinct查询。我很快就发现这是不可能的。微软有一个文章演示了一个简单的Distinct,但它不够健壮,无法满足我的需求。它只允许指定一个列,而我需要不同时间不同数量的列。我重写了微软的示例,直到我最终能够处理多个列、过滤/条件和排序。

Using the Code

在该对象中,只有一个主要方法称为SelectDistinct()。它被重载了大约十次,以提供编码的灵活性。要使用我的对象,只需实例化对象并调用SelectDistinct方法。

我包含了一个演示应用程序,允许您指定SQL连接字符串和查询或存储过程,以便您可以测试SelectDistinct对象的性能和准确性。

dsh = New clsDSH(dt)
Dim dt2 as DataTable = dsh.SelectDistinct(Fields,Filter,Sort)
'Or
dsh = New clsDSH()
Dim dt2 as DataTable = dsh.SelectDistinct(dt,Fields,Filter,Sort)

代码示例假设"dt"已经被定义并填充。请注意,在这两种情况下,"dsh"对象实际上都会保留DataTable的副本,可以通过.Table属性访问。

完成该对象后,我发现它可以运行得更快。我最初是用两个DataTable完成的,只取唯一的行并将它们放入新表中,然后从对象中返回该表。令我沮丧的是,这比任何人都能想象到的都要慢。长话短说,我最终对每一行DataRow进行了哈希处理,并使用该哈希值进行比较并生成一个Distinct表。不幸的是,DataRow.GetHashCode()方法不够Distinct,无法使用。幸运的是,我发现如果我仔细地将每一行DataRow转换为字符串,然后执行String.GetHashCode(),它就奏效了。而且速度很快。目前,该对象可以在一秒多一点的时间内处理40,000条记录,并将其转换为大约2000条Distinct记录!也许可以更快,也许不行。**更新** - 基于**srkinyon**提供的一些代码,我重写了该对象以包含他的一些想法,并重新组织并删除了不再需要的内容。这包括前面提到的哈希处理。现在,该对象能够在0.6秒左右的时间内对包含超过40,000行的DataTable执行Distinct查询。这比以前快了约3倍。现在,这真的很快。我必须承认,我的代码中也有一些小的冗余。尽管如此,速度的提升大部分似乎来自于我现在将数据列值存储为它们本身的类型;"object"而不是将它们转换为字符串,然后进行哈希处理。我也不得不承认,哈希处理对于Distinct目的来说并不足够可靠。所以,感谢**srkinyon**。如果有人能做得更快或更好,请随时提出。

我还出于好玩添加了几个额外的属性。一个是RecordCount,应该不言自明。还有ElapsedTime,它存储上一次Distinct调用所花费的总时间。有点浪费时间,但我想知道对象的运行速度。

关注点

我在开发过程中发现,即使是最小的事情也会极大地拖慢你的速度。甚至一个.Trim()或一个.Split()。所以要明智地使用它们。

另外,我用C#写了同一个对象,它也可以在这个网站上找到,所以你可以两种方式都拥有 :)顺便说一句,这两种语言之间的速度没有实际区别。

历史

无。

© . All rights reserved.