我有一个对象集合(使用 linq to SQL 映射到数据库中的行)。我想根据它们的一些属性对这些对象进行重复数据删除。我可以用 linq to sql 查询来做到这一点吗?
例如,如果我有一组具有属性名称、出生日期、ssn 和学习领域的学生,我如何根据姓名、出生日期和 ssn(但不是学习领域)从该列表中选择不同的学生。有没有一种优雅的方法可以用 LINQ 做到这一点?如果没有,还有另一种优雅的方法吗?
您可以使用Distinct
自定义的IEqualityComparer
. 例如,这是我非常喜欢的一个:
public class PropertyEqualityComparer<TObject, TProperty>
: IEqualityComparer<TObject>
{
Func<TObject, TProperty> _selector;
IEqualityComparer<TProperty> _internalComparer;
public PropertyEqualityComparer(Func<TObject, TProperty> propertySelector,
IEqualityComparer<TProperty> innerEqualityComparer = null)
{
_selector = propertySelector;
_internalComparer = innerEqualityComparer;
}
public int GetHashCode(TObject obj)
{
return _selector(obj).GetHashCode();
}
public bool Equals(TObject x, TObject y)
{
IEqualityComparer<TProperty> comparer =
_internalComparer ?? EqualityComparer<TProperty>.Default;
return comparer.Equals(_selector(x), _selector(y));
}
}
//and here's a class to help instantiate it with anonymous objects
public static class PropertyEqualityComparer
{
public static PropertyEqualityComparer<TObject, TProperty>
GetNew<TObject, TProperty>(Func<TObject, TProperty> propertySelector)
{
return new PropertyEqualityComparer<TObject, TProperty>
(propertySelector);
}
public static PropertyEqualityComparer<TObject, TProperty>
GetNew<TObject, TProperty>
(Func<TObject, TProperty> propertySelector,
IEqualityComparer<TProperty> comparer)
{
return new PropertyEqualityComparer<TObject, TProperty>
(propertySelector, comparer);
}
}
以下是您将如何在示例中使用它:
var result = students.Distinct(
PropertyEqualityComparer.GetNew(s => new { s.Name, s.DOB, s.SSN }));
您可以按匿名对象分组,该对象将包含您要分组的所有字段:
from s in students
group s by new { s.Name, s.DateOfBirth, s.SSN } into g
select g
实际上,您可以从每个组中选择第一项
...
select g.First()
或者使用其他一些逻辑,比如聚合:
...
select new {
g.Key.Name,
g.Key.DateOfBirth,
g.Key.SSN,
Fields = g.Select(x => x.FieldOfStudy).ToList()
}