在DataView行中查找下一个更高的值

本文关键字:下一个 查找 DataView | 更新日期: 2023-09-27 18:25:49

我有一个DataView,它在行PathName中包含以下名称:

"C:'$Recycle.Bin'S-1-5-21-1993492240-2256127134-121505747-1000"
"C:'$Recycle.Bin'S-1-5-21-1993492240-2256127134-121505747-1004"
"C:'Program Files (x86)'Common Files'microsoft shared'DAO'dao360.dll"
"C:'Program Files (x86)'Common Files'microsoft shared'ink'1.0'Microsoft.Ink.dll"
"C:'Program Files (x86)'Common Files'microsoft shared'ink'de-DE'InkObj.dll.mui"
"C:'Windows'System32'de-DE'Query.dll.mui"
"C:'Windows'System32'de-DE'query.exe.mui"
"C:'Windows'System32'de-DE'quser.exe.mui"
"C:'Windows'System32'de-DE'Qutil.dll.mui"
"C:'Windows'System32'DriverStore'FileRepository'bth.inf_amd64_neutral_de0494b6391d872c'bthport.sys"
"C:'Windows'System32'DriverStore'FileRepository'bth.inf_amd64_neutral_de0494b6391d872c'BTHUSB.SYS"
"C:'Windows'System32'DriverStore'FileRepository'bth.inf_amd64_neutral_e54666f6a3e5af91'bthenum.sys"

对于任何给定的路径,我都需要获取子文件夹

路径的子文件夹"C:''"

"$Recycle.Bin"
"Program Files (x86)"
"Windows"

我目前正在做的是:

  • 扩展当前行筛选器:MyDataView.rowfilter += " and (PathName LIKE 'c:'%')"
  • 首先找到C:'$Recycle.Bin'S-1-5-21-1993492240-2256127134-121505747-1000并提取C:'$Recycle.Bin
  • 然后,我遍历这些行,直到找到与C:'$Recycle.Bin不同的内容,如C:'Program Files (x86)'...

DataView可能包含100.000个或更多的条目,因此这种方式需要很长时间。

一种可能性是在每次命中后扩展行过滤器:

MyDataView.rowfilter += " and (PathName LIKE 'c:'%')" + " and (PathName NOT LIKE 'C:'$Recycle.Bin'%')". 

但是路径名可能会变得很长,这将导致行筛选器中的堆栈溢出。

还有其他方法吗,比如"获得下一个更高的值"?

编辑
必须找到任何给定路径的子文件夹,而不仅仅是c:'

在DataView行中查找下一个更高的值

如果我理解正确,这可以用一行Linq来完成(为了可读性,拆分为多行)

var dirs = dv.Table
             .AsEnumerable()
             .Select(x => Path.GetDirectoryName(x.Field<string>("PathName")))
             .Distinct();

诀窍在于使用Path.GetDirectoryName从每一行中提取字段PathName的值,并使用Select方法创建可枚举的字符串。然后Distinct方法只返回集合中唯一的目录名。

如果您的DataView已针对其他条件进行了筛选,并且您希望保留此条件以排除记录的子集,则可以使用Where方法提取所需的记录。例如,要排除所有以"C:''WINDOWS"开头的记录,可以编写

var dirs = dv.Table
             .AsEnumerable()
             .Where(k => !k.Field<string>("PathName").StartsWith(@"C:'WINDOWS"))
             .Select(x => Path.GetDirectoryName(x.Field<string>("PathName")))
             .Distinct();