2015-12-06 4 views
1

У меня есть DataView, который в строке PathName содержит имена, как:Найти следующий более высокое значение в DataView строке

"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" 

Для любого данного пути мне нужно получить вложенные папки.

Sub папки для пути "C: \"

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

Что я сейчас делаю это:

  • Продлить настоящий RowFilter: 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 и больше записей, так что этот способ занимает очень много времени.

Одной из возможностей было бы расширить RowFilter после каждого удара:

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

Но имена путей могут получить очень долго, и это приведет к переполнению стека в RowFilter.

Есть ли другой способ, например, «получить следующую более высокую ценность»?

Редактировать
Подпапка должна быть найдена для любого данного пути не только для c:\

+0

Вы ищете только первую вложенную C или вам нужен каждый подкаталог? – Steve

+0

@steve для любого пути. Я редактировал вопрос. – boboes

ответ

1

Если я вас правильно понял это может быть сделано с одной линией 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(); 
+0

Спасибо, звучит очень обещающе. Но для этого мне нужно преобразовать его в DataTable. Не 'MyDataView.ToTable()' создает копию всего DataView? – boboes

+0

DataView имеет ссылку на исходную таблицу, нет необходимости создавать новую копию существующей таблицы.Как вы создаете переменную MyDataView? – Steve

+0

Но 'MyDataView.Table' не содержит строковый фильтр. Вот почему я использую DataView. – boboes

 Смежные вопросы

  • Нет связанных вопросов^_^