2013-10-23 8 views
6

Ich habe zwei Listen mit eigenen Daten gefüllt. lässt sich sagen, es gibt zwei Modelle Human und AnotherHuman. Jedes Modell enthält verschiedene Felder, jedoch haben sie einige gemeinsame Felder wie LastName, FirstName, Birthday, PersonalID.Ausschließen von Elementen einer Liste in einem anderen mit anderen Objektdatentypen, LINQ?

List<Human> humans = _unitOfWork.GetHumans(); 
List<AnotherHuman> anotherHumans = _unitofWork.GetAnotherHumans(); 

Ich mag die Elemente aus der Liste auszuschließen anotherHumans wo LastName, FirstName, Birthday alle gleich die entsprechenden Felder eines Elements sind in der Liste humans.

Allerdings, wenn ein Artikel in anotherHumans Liste PersonalID und Element in der Liste humans haben die gleiche PersonalID, dann ist es genug Human mit AnotherHuman dieses PersonalID, sonst durch LastName, FirstName and Birthday nur zu vergleichen.

Ich habe versucht, neue Liste von dublicates zu erstellen und von anotherHumans auszuschließen:

List<AnotherHuman> duplicates = new List<AnotherHuman>(); 
foreach(Human human in humans) 
{ 
    AnotherHuman newAnotherHuman = new AnotherHuman(); 
    newAnotherHuman.LastName = human.LastName; 
    newAnotherHuman.Name= human.Name; 
    newAnotherHuman.Birthday= human.Birthday; 
    duplicates.Add(human) 
} 
anotherHumans = anotherHumans.Except(duplicates).ToList(); 

Aber wie kann ich PersonalID aus beiden Listen vergleichen, wenn sie präsentiert (es ist nullable). Gibt es eine Möglichkeit, eine neue Instanz von AnotherHuman und eine Liste von Duplikaten zu entfernen und nur LINQ zu verwenden?

Vielen Dank im Voraus!

Antwort

9

Statt neue Objekte zu schaffen, wie etwa die Eigenschaften als Teil der Linq-Abfrage überprüft

List<Human> humans = _unitOfWork.GetHumans(); 
List<AnotherHuman> anotherHumans = _unitofWork.GetAnotherHumans(); 

// Get all anotherHumans where the record does not exist in humans 
var result = anotherHumans 
       .Where(ah => !humans.Any(h => h.LastName == ah.LastName 
           && h.Name == ah.Name 
           && h.Birthday == ah.Birthday 
           && (!h.PersonalId.HasValue || h.PersonalId == ah.PersonalId))) 
       .ToList(); 
+0

Für jedes Element in anotherHumans, dann würden Sie den Menschen Sammlung iterieren müssen, so Die Leistung würde sich erheblich verschlechtern, wenn die Größe der Sammlungen zunimmt. – spender

+0

Dies wird nur Elemente vergleichen, die eine 'PersonalID' haben. Ich glaube nicht, dass dies gefragt wurde. – spender

+0

Immer noch nicht so gut, denn in dem Fall, dass eine "PersonalID" vorhanden ist, ist es nicht erforderlich, den Nachnamen, den Namen und das Alter zu überprüfen, richtig? – spender

1
var nonIdItems = anotherHumans 
    .Where(ah => !ah.PersonalID.HasValue) 
    .Join(humans, 
     ah => new{ah.LastName, 
      ah.FirstName, 
      ah.Birthday}, 
     h => new{h.LastName, 
      h.FirstName, 
      h.Birthday}, 
     (ah,h) => ah); 
var idItems = anotherHumans 
    .Where(ah => ah.PersonalID.HasValue) 
    .Join(humans, 
     ah => ah.PersonalID 
     h => h.PersonalID, 
     (ah,h) => ah); 
var allAnotherHumansWithMatchingHumans = nonIdItems.Concat(idItems); 
var allAnotherHumansWithoutMatchingHumans = 
     anotherHumans.Except(allAnotherHumansWithMatchingHumans); 
13
var duplicates = from h in humans 
       from a in anotherHumans 
       where (h.PersonalID == a.PersonalID) || 
         (h.LastName == a.LastName && 
         h.FirstName == a.FirstName && 
         h.Birthday == a.Birthday) 
       select a; 

anotherHumans = anotherHumans.Except(duplicates); 
+1

Schön, sauber. +1 – NinjaNye

+1

diese Variante funktioniert auch super, danke! –

+1

Schön und sauber im Code, Danke –

Verwandte Themen