2015-02-03 3 views
3

У меня есть список, содержащий множество объектов с этим определением:Сравнение и слияние список объектов

Public Class Helper 
    Public Property UserPrincipal As UserPrincipal 
    Public Property Groups As New List(Of String) 
    Public Property Server As New List(Of String) 
End Class 

Предположим, один объект выглядит следующим образом:

UserPrincipal.Name = Jan 
Groups = {group_1, group_2, group_3} 
Server = {Server1} 

И еще один:

UserPrincipal.Name = Jan 
Groups = {group_1, group_3} 
Server = {Server2} 

Теперь я хочу проверить свойство «Группы» каждого объекта и создать новый объект, если «Группы» одного объекта содержат «G» roups "другого объекта.

Таким образом, новый список объектов должен выглядеть следующим образом:

UserPrincipal.Name = Jan 
Groups = {group_1, group_2, group_3} 
Server = {Server1, Server2} 

Возможно ли это с помощью LINQ?

Спасибо и уважением, Jan

обновление: 10:42: Изменен тип «Server'-свойства из строки в список (строки)

Update 12:04: Позвольте мне попытаться прояснить мой вопрос. Задача состоит в сборе членов локальной группы серверов. Для этого я подключаюсь к каждому серверу с помощью нового основногоконтекста с правильными учетными данными, получаю нужную группу (это группа пользователей удаленных рабочих столов) и получаю всех членов этой группы. С помощью этой информации я заполняю упомянутый «helper'-object», содержащий userprincipal (который является членом группы), группу (группы пользователей группы удаленных рабочих столов) и имя сервера.

Итак, у меня есть n * Вспомогательные объекты, где n - количество серверов.

Теперь есть два требования: допустим, у меня есть два сервера, и server2. Все равно, но имя сервера отличается, поэтому я хочу только один объект с свойством Server = {server1, server2}.

И второе требование в основном похоже на первое, но: сделайте это, если свойство Groups содержит хотя бы одну уникальную корреляцию и добавляет эту группу в список, если ее еще нет.

Не знаю, теперь ли это яснее :) Покажет короткий пример.

Объект 1:
UserPrincipal.Name = Jan
Группы = {Домен-пользователей}
Server = {} SERVER1

Объект 2:
UserPrincipal.Name = Jan
Группы = {Domain -Пользователи}
Сервер = {Сервер2}

Ожидаемое объект:
UserPrincipal.Имя = Jan
Группы = {Домен-пользователей}
Сервер = {Сервер1, Сервер2}

Пример 2:
Объект 1:
UserPrincipal.Name = Jan
Группы = {Домен-пользователей, тест -пользователей}
Server = {} sERVER1

Объект 2:
UserPrincipal.Name = Jan
Группы = {Test-пользователей}
Server = {} Сервер2

Ожидаемый объект:
UserPrincipal.Name = Jan
Группы = {Домен-пользователей, тест-пользователей}
Server = {Сервер1, Сервер2}

И последнее, Puhh:

Объект 1:
UserPrincpial.Name = Jan
Группы = {Test-пользователей}
Server = {} Сервер1

Объект 2:
UserPrincipal.Name = Jan
Группы = {Домен-пользователей}
Server = {Сервер1} или {Сервер2} и т.д. не имеет значения.

Ожидаемый результат: Свойства свойства изменения groups совершенно разные.

+0

Вы не можете изменить тип свойства 'Server' из строки в' List (Of string) '. Таким образом, вам нужно либо использовать список в первую очередь, либо использовать строку и конкатють все с запятой (или другим разделителем). –

+0

Вы можете, вам просто не разрешено использовать опцию Strict On. Но учтите, что это не рекомендуется – lsteinme

+0

Как относится к 'UserPrincipal', имеет ли та же группа одна и та же' UserPrincipal'? Или кто из группы вы хотите сохранить, первый? –

ответ

0

В соответствии с обновленным вопросом и ваши комментариями это кажется, что вы хотите:

Dim upGroups = From helper In helpers 
       Group helper By helper.UserPrincipal Into Group 
       Select New Helper With { 
       .UserPrincipal = UserPrincipal, 
       .Groups = Group.SelectMany(Function(h) h.Groups).Distinct().ToList(), 
       .Server = Group.SelectMany(Function(h) h.Server).Distinct().ToList() 
       } 
Dim newHelpers = upGroups.ToList() 

Старого ответ

Вы можете использовать Groups.Intersect(h.Groups).Any() чтобы проверить, какие помощник содержат пересекающиеся группы. Затем вы можете использовать цикл для их объединения:

Dim query = From helper In helpers 
      Let group = helpers.Where(Function(h) helper.Groups.Intersect(h.Groups).Any()) 

Dim processed As New HashSet(Of Helper)() 
Dim newHelpers As New List(Of Helper) 
For Each x In query 
    If x.group.Any(AddressOf processed.Contains) Then 
     ' was already processed, skip ' 
     Continue For 
    End If 
    Dim mergedHelper = New Helper With { 
       .UserPrincipal = x.group.First().UserPrincipal, 
       .Groups = x.group.SelectMany(Function(h) h.Groups).Distinct().ToList(), 
       .Server = x.group.SelectMany(Function(h) h.Server).Distinct().ToList() 
      } 
    newHelpers.Add(mergedHelper) 
    For Each helperInGroup In x.group 
     processed.Add(helperInGroup) 
    Next 
Next 
+0

Привет, Тим, спасибо за это, попробуем это после обеда. – Jan

+0

Кажется, что-то ошибка. Он выплескивает около 5 записей, только когда мой первоначальный список содержит около 20 000) записей. :) – Jan

+0

@Jan: так почему же это неправильно? Ваше требование состояло в том, чтобы объединить всех помощников, которые пересекают группы, не так ли? ** Изменить ** Подождите, я вижу, что вы отредактировали вопрос. –