C# 用不同的对象数据类型排除另一个列表中的项目,LINQ?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19539822/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 15:14:23  来源:igfitidea点击:

Exclude items of one list in another with different object data types, LINQ?

c#asp.net-mvclinqlist

提问by Gyuzal R

I have two lists filled with their own data. lets say there are two models Humanand AnotherHuman. Each model contains different fields, however they have some common fields like LastName, FirstName, Birthday, PersonalID.

我有两个列表,里面装满了他们自己的数据。假设有两个模型HumanAnotherHuman. 每个模型都包含不同的字段,但是它们有一些共同的字段,例如LastName, FirstName, Birthday, PersonalID.

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

I would like to exclude the items from list anotherHumanswhere LastName, FirstName, Birthdayare all equal to the corresponding fields of any item in list humans.

我想从 listanotherHumans中排除项目,其中LastName, FirstName, Birthday都等于list中任何项目的相应字段humans

However if any item in anotherHumanslist has PersonalIDand item in list humanshave the same PersonalID, then it is enough to compare Humanwith AnotherHumanonly by this PersonalID, otherwise by LastName, FirstName and Birthday.

但是,如果在任何项目anotherHumans列表具有PersonalID和列表项humans具有相同的PersonalID,那么它是足够的,比较HumanAnotherHuman这个只PersonalID,否则LastName, FirstName and Birthday

I tried to create new list of dublicates and exclude it from anotherHumans:

我试图创建新的重复列表并将其排除在anotherHumans

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();

But how can I compare PersonalIDfrom both lists if it presents (it is nullable). Is there any way to get rid from creating new instance of AnotherHuman and list of duplicates and use LINQ only?

但是,PersonalID如果它存在,我如何从两个列表中进行比较(它可以为空)。有什么方法可以摆脱创建 AnotherHuman 的新实例和重复列表并仅使用 LINQ 的方法吗?

Thanks in advance!

提前致谢!

采纳答案by NinjaNye

Instead of creating new objects, how about checking the properties as part of the linq query

不是创建新对象,而是检查属性作为 linq 查询的一部分

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();

回答by spender

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);

回答by Sergey Berezovskiy

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);