我在C#中有两个列表。我需要一个 LINQ 查询来仅比较和列出不匹配的行。
List<First> firstList;
List<Second> secondList;
both have the unique property called ID;
首页列表:
ID Desc1 Desc2
1 aaa mmm
2 bbb fff
3 ccc ttt
4 ddd yyy
5 eee ggg
第二列表:
ID Desc1 Desc2 Status
1 aaa mm P
2 bbb fff S
3 ccc ttt P
4 ddd yy S
5 eee ggg P
结果:
ID Desc1 Desc2 Status
2 aaa mm P
4 ddd yy S
我想将第一个列表中的 Desc1 和 Desc2 与第二个列表进行比较,并且需要不匹配的项目的状态。
一些查找结果的方法(lambda,linq(:
var query0 = secondList.Where(item => firstList.All(f => !item.Desc1.Equals(f.Desc1) || !item.Desc2.Equals(f.Desc2)));
或
var query1 =
from item in secondList
where firstList.All(f => !item.Desc1.Equals(f.Desc1) || !item.Desc2.Equals(f.Desc2))
select item;
如果你想把结果放在一个列表中而不是枚举中,你只需在最后添加 Tolist((:
var list0 = secondlist.Where(item => firstlist.All(f => !item.Desc1.Equals(f.Desc1) || !item.Desc2.Equals(f.Desc2))).ToList();
要在评论中回答您的问题:
如果要迭代或选择特定ID,可以这样做:
foreach(var item in query0)
{
Console.WriteLine($"ID:{item.ID}, Desc1:{item.Desc1}, Desc2:{item.Desc2}, Status:{item.Status}");
}
//if you want to query a particular id:
var queryid = query0.Where(item => item.ID == particularID);
请参阅下文。您需要在两个列表之间做并集,然后删除交集。您将需要实现IEqualityComparer接口。
void Main()
{
List<UserProfile> u1 = new List<UserQuery.UserProfile>(){
new UserProfile(){ID = 1, FirstName = "Super" , LastName = "Man"},
new UserProfile(){ID=2, FirstName = "Spider", LastName="Man"},
new UserProfile(){ID=3, FirstName = "Bat", LastName="Man"}
};
List<UserProfile> u2 = new List<UserProfile>(){
new UserProfile(){ID = 1, FirstName="Super", LastName="Man"},
new UserProfile(){ID = 2, FirstName="Thor", LastName="Ragnarok"},
new UserProfile(){ID = 3, FirstName="Hulk", LastName="Baner"}
};
// u1.Intersect(u2, new UserProfileComparer())
// .ToList()
// .ForEach(x => Console.WriteLine(x.Name));
// u1.Except(u2, new UserProfileComparer())
// .ToList()
// .ForEach(x => Console.WriteLine(x.Name));
// (u1 + u2) - (u1*u2)
u1.Union(u2, new UserProfileComparer())
.Except(u1.Intersect(u2, new UserProfileComparer()))
.Distinct()
.ToList()
.ForEach(x => Console.WriteLine(x.Name));
}
class UserProfile
{
public int ID {get;set;}
public string Name => LastName + "," + FirstName;
public string FirstName {get;set;}
public string LastName {get;set;}
}
class UserProfileComparer : IEqualityComparer<UserProfile>
{
public bool Equals(UserProfile item1, UserProfile item2)
{
if (object.ReferenceEquals(item1, item2))
return true;
if (item1 == null || item2 == null)
return false;
return item1.FirstName.Equals(item2.FirstName) &&
item1.LastName.Equals(item2.LastName);
}
public int GetHashCode(UserProfile item)
{
return new { item.FirstName, item.LastName }.GetHashCode();
}
}
我建议不要像其他答案中提到的那样使用 !=,而是使用连接。如果你的列表很大!=会消耗大量的处理时间。
以下代码可能看起来很丑陋,但确实达到了目的并且速度更快。
var unmatchedRec = (from p in lstFiles1
join f in lstFiles2
on new
{
p.FileName,
p.PageNumber
} equals new
{
f.FileName,
f.PageNumber
} into fg
from fgi in fg.DefaultIfEmpty()
select new { p, fgi })
.Where(t => t.fgi == null)
.Select(t => t.p)
.ToList();