我认为Id
是一个标识符,因此具有相同Id
的任何两个c
实际上是相同的并且具有相同的PetList
。因此,我们可以GroupBy
只是Id
,并获得PetList
另一种方式:
var viewModel = reports
.GroupBy(c => c.Id)
.Select(g => new ArmReportModel
{
PetList = g.First().PetList, // Might need FirstOrDefault() with some providers
Pets = g.Count()
});
除非那个,我想先确保我可以用一个IEqualityComparer<T>
与GroupBy
。如果提供者允许的话,那么没有问题。否则,我开始:
reports.Select(c => new {c.Id, c.PetList}).AsEnumerable()
这将会从供应商到内存所需的最低限度,从而使LINQ到对象提供者可以从这一点上可以使用。
我需要能够定义一个IEqualityComparer<T>
一些T
,所以我停止使用匿名类型:
private class IdAndList
{
public int Id { get; set; }
public List<string> PetList { get; set; }
}
private class ReportIdAndPetListComparer : IEqualityComparer<IdAndList>
{
public bool Equals(IdAndList x, IdAndList y)
{
if (ReferenceEquals(x, y)) return true;
if (x == null || y == null) return false;
if (x.Id != y.Id) return false;
if (x.PetList == null) return y.PetList == null;
if (y.PetList == null) return false;
int count = x.PetList.Count;
if (y.PetList.Count != count) return false;
for (int i = 0; i != count; ++i)
if (x.PetList[i] != y.PetList[i]) return false;
return true;
}
public int GetHashCode(IdAndList obj)
{
int hash = obj.Id;
if (obj.PetList != null)
foreach (string pet in obj.PetList)
hash = hash * 31 + pet.GetHashCode();
return hash;
}
}
有的为空测试PetList
s时,可以删除的,如果你知道这是不可能的。
现在:
var viewModel = reports.Select(c => new IdAndList{c.Id, c.PetList}).AsEnumerable()
.GroupBy(c => c, new ReportIdAndPetListComparer())
.Select(g => new ArmReportModel
{
PetList = g.Key.PetList,
Pets = g.Count()
});
或者,如果供应商不能处理构建IdAndPetList
类型,那么:
var viewModel = reports.Select(c => new {c.Id, c.PetList})
.AsEnumerable()
.Select(c => new IdAndList{c.Id, c.PetList})
.GroupBy(c => c, new ReportIdAndPetListComparer())
.Select(g => new ArmReportModel
{
PetList = g.Key.PetList,
Pets = g.Count()
});
你怎么组由一个列表?如果你有一个为两个宠物列表定义“平等”的类,那么你可以将它传递给'GroupBy' - 否则默认使用引用相等。 –
如此类似于自定义IComparable? – McArthey
是 - 创建一个实现['IEqualityComparer'](https://msdn.microsoft.com/en-us/library/ms132151(v = vs.110).aspx)的类并将其传递给'GroupBy'。请确保遵循[实现'GetHashCode']的指导原则(https://blogs.msdn.microsoft.com/ericlippert/2011/02/28/guidelines-and-rules-for-gethashcode/)“。 –