我正在尝试编写一个方法,最终会给我一组记录,这些记录在我引用的不同集合中不再有相应的记录。
结构类似于:
public class A
{
int id {get; set;}
int recId {get; set;}
string category {get; set;}
}
public class B
{
int recId {get; set;}
string category {get; set;}
}
到目前为止,我有以下一点LINQ给我收集了丢失的记录,但这只给了我任何遗漏的recId
:
var noLongerHaveRecordInCollectionB =
CollectionA.Select(x => x.recId).Except(CollectionB.Select(x => x.recId));
我需要List<A>
的每条记录:
1。)recId
中不再有CollectionB
。
OR
2.。)recId
category
和CollectionB
的记录
对于示例,有可能在CollectionA
内有2条记录具有相同的recId
但category
不同。
如果CollectionB
现在只包含recId
的1条记录,我会删除CollectionA
中没有相应类别的记录。
所以最终的问题是如何将noLongerHaveRecordInCollectionB
填入已经针对<T>
检查过的所有CollectionB
A而不仅仅是recId
目前所做的,{I}}想要整个对象。
编辑:输入/结果
CollectionA
1,2254,A类
2,2236,A类
3,2415,B类
4,1275,B类&lt; ---同一人如下,差异类别
5,1275,C类&lt; ---与上述相同的人,差异类别
CollectionB
2254,A类
2415,B类
1275,C类
预期结果
我希望(来自CollectionA)在我的列表中突出显示以下id以供删除:2,4
答案 0 :(得分:2)
您可以使用带有Where
条件的||
子句来简单地实现所需内容。无需寻求复杂的解决方案。
var result = collectionA.Where(a => collectionB.Any(b => a.recId == b.recId && a.Category != b.Category)
|| !collectionB.Any(b => b.recId == a.recId));
OLD ANSWER
您可以为您的类实现IEqualityComparer,并根据您感兴趣的字段比较对象。例如,实现Equals方法,如下所示:
public bool Equals(A a, B b)
{
return a.recId == b.recId && a.category == b.category ;
}
然后只需调用Except方法并传递comparer
:
var resultList = CollectionA .Except(CollectionB, new MyEqualityComparer());
或者如果您在课堂上实施,而不是单独的comparer
,则可以致电Except
:
var resultList = CollectionA .Except(CollectionB);
请注意,您还需要实施GetHashCode
方法。
<强>更新强>
如果您想使用IEqualityComparer<T>
,可以从第二个列表中创建一个新列表:
var secondListA = CollectionB.Select(x=> new A(){Category=x.Category, recId=x.recId});
然后创建您的Comparer
:
sealed class MyComparer : IEqualityComparer<A>
{
public bool Equals(A x, A y)
{
if (x == null)
return y == null;
else if (y == null)
return false;
else
return x.recId== y.recId&& x.Category == y.Category;
}
public int GetHashCode(A obj)
{
return obj.recId.GetHashCode();
}
}
使用Except()
重载,通过使用指定的IEqualityComparer<T>
比较值来产生两个序列的集合差异。:
var result = CollectionA.Except(secondListA, new MyComparer ());
但我认为你应该使用简单的Where
过滤器,因为创建A
类型的新列表会导致大量的性能改变。
答案 1 :(得分:1)
您始终可以使用Enumerable.Except
等设置方法,并使用其他方法Join
来获取完整数据。
我需要
List<A>
的每条记录: 1.)recId
中不再有CollectionB
。
var onlyInA = CollectionA.Select(x => x.recId).Except(CollectionB.Select(x => x.recId));
var dataOnlyInA = from a in CollectionA
join recId in onlyInA
on a.onlyInA equals recId
select a;
List<A> result = dataOnlyInA.ToList();
2.。)
中不再有匹配recId
category
和CollectionB
的记录
也许:
var canBeRemovedFromA = CollectionA
.Where(a => CollectionB.Any(b => a.recID == b.recId && a.category!= b.category));
这不会检查是否至少有一个匹配的类别。目前尚不清楚这是否必须。