2015-11-09 2 views
1

У меня есть два списка, которые я хочу объединить в один список. Список компьютеров в Active Directory и список компьютеров в SCCM.C# слияние двух списков объектов

lišta содержит:

public string ComputerName { get; set; } 
    public string OperatingSystem { get; set; } 
    public DateTime? LastLogon { get; set; } 

LISTB содержит:

public string ComputerName { get; set; } 
    public DateTime[] AgentTime { get; set; } 
    public string LastLogonUserName { get; set; } 

Я хочу слиться с помощью имя_компьютера, но если я сделать это с помощью функции присоединения, используя (пример):

var query = from ObjectA in ListA 
      join ObjectB in ListB on ObjectA.ComputerName equals ObjectB.ComputerName 
      select new { computername = ObjectA.ComputerName, lastlogonusername = ObjectB.LastLogonUserName }; 

это только показывает результат, который является обоими списками. Я хочу, чтобы список компьютеров в AD с дополнительной информацией для тех, которые также находятся в SCCM

ListC содержащий:

public string ComputerName { get; set; } 
    public string OperatingSystem { get; set; } 
    public DateTime? LastLogon { get; set; } 
    public DateTime[] AgentTime { get; set; } 
    public string LastLogonUserName { get; set; } 

Что такое лучший способ сделать это?

+1

выход вы получаете результат вашей внутренней присоединиться , –

+1

См. Левое внешнее соединение на следующей веб-странице: https://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b – jdweng

+0

Вы создаете динамический объект 'new {}'. Создайте собственный класс, если вам нужно. –

ответ

2

Вам необходимо внешнее соединение:

var query = 
     from ObjectA in ListA 
     join ObjectB in ListB on ObjectA.ComputerName equals ObjectB.ComputerName into tmp 
     from ObjectB in tmp.DefaultIfEmpty() 
     select new { computername = ObjectA.ComputerName, lastlogonusername = ObjectB?.LastLogonUserName }; 

Обратите внимание на использование ?. на ObjectB: это потому, что, если нет соответствующего элемента в ListB, ObjectB будет нулевым.

(если вы не используете C# 6, вы можете сделать ObjectB != null ? ObjectB.LastLogonUserName : null вместо)

+0

Спасибо Томас за быстрый ответ. Из комментариев, представленных выше, я понял это с помощью левого внешнего соединения. Но спасибо, указав меня на «. не соответствует процедуре вместо ObjectB == null? "": ObjectB.LastLogonUserName. Спасибо – user2931144

1

Почему бы не добавить все в один список, а просто получить отдельный список по имени ComputerName?

// Convert all B objects to A objects 
var objectBsAsAs = ListB.Select(x => new ObjectA() { ComputerName = x.ComputerName, LastLogonUserName = x.LastLogonUserName }); 
// Add all B objects to the list of A objects 
var allComputers = ListA.AddRange(objectBsAsAs); 
// Get a distinct list based on ComputerName 
var distinct = ListA.Distint(new ComputerNameComparer()); 

private class ComputerNameComparer : IEqualityComparer<ObjectA> 
{ 
    public bool Equals(ObjectA a, ObjectA b) 
    { 
     return a.ComputerName == b.ComputerName; 
    } 
} 
+0

Также спасибо – user2931144

+0

Добро пожаловать. Вы можете поблагодарить, ответив на голосование! :) – timothyclifford

1

Нечто подобное могло бы помочь -

 var l1 = new List<A> 
     { 
      new A 
      { 
       ComputerName = Dns.GetHostName(), 
       LastLogon = DateTime.Now, 
       OperatingSystem = "Windows" 
      } 
     }; 

     var l2 = new List<B> 
     { 
      new B 
      { 
       AgentTime = new DateTime[]{DateTime.Now}, 
       ComputerName = Dns.GetHostName(), 
       LastLogonUserName = "me" 
      } 
     }; 


     var o = from r in l2 
       join q in l1 on r.ComputerName equals q.ComputerName 
       into grp 
       from p in grp.DefaultIfEmpty() 
       select new C 
       { 
        AgentTime = r.AgentTime, 
        ComputerName = p.ComputerName, 
        LastLogon = p.LastLogon, 
        OperatingSystem = p.OperatingSystem, 
        LastLogonUserName = r.LastLogonUserName 
       }; 
+0

Также благодаря вам. – user2931144

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