我可以使用linq查询基于多个字段复制对象集合吗?

时间:2013-06-10 16:39:09

标签: .net linq

我有一组对象(使用linq to SQL映射到数据库中的行)。我想基于它们的一些属性去除这些对象。我可以使用linq to sql查询执行此操作吗?

例如,如果我有一系列具有属性名称,出生日期,ssn和学习领域的学生,我如何根据姓名,出生日期和ssn(但不是研究领域)从该列表中选择不同的学生)。使用LINQ有一种优雅的方法吗?如果没有,还有另一种优雅的方法吗?

2 个答案:

答案 0 :(得分:1)

您可以使用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 }));

答案 1 :(得分:0)

您可以按匿名对象进行分组,该对象将包含您要分组的所有字段:

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