Отличительный в структуре Entity - PullRequest
7 голосов
/ 16 декабря 2011

У меня есть список объектов, некоторые из которых имеют одинаковые идентификаторы, поэтому я хотел бы удалить дублирующиеся элементы.

Я пробовал что-то вроде этого:

List<post> posts = postsFromDatabase.Distinct().ToList();

Но это не работает!

Поэтому я написал этот метод, чтобы избежать дубликатов:

public List<Post> PostWithOutDuplicates(List<Post> posts)
    {
        List<Post> postWithOutInclude = new List<Post>();
        var noDupes = posts.Select(x => x.Id).Distinct();
        if (noDupes.Count() < posts.Count)
        {
            foreach (int idPost in noDupes)
            {
                postWithOutInclude.Add(posts.Where(x => x.Id == idPost).First());
            }
            return postWithOutInclude;
        }
        else
        {
            return posts;
        }
    }

Есть идеи, как улучшить производительность ??

Заранее спасибо.

Ответы [ 3 ]

26 голосов
/ 16 декабря 2011

Это красиво и просто:

List<Post> posts = posts
.GroupBy(x => x.Id)
.Select(x => x.FirstOrDefault())

Но если вы хотите написать это правильно, я бы посоветовал вам написать это так:

public class PostComparer : IEqualityComparer<Post>
{
    #region IEqualityComparer<Post> Members

    public bool Equals(Post x, Post y)
    {
        return x.Id.Equals(y.Id);
    }

    public int GetHashCode(Post obj)
    {
        return obj.Id.GetHashCode();
    }

    #endregion
}

Какэто даст вам больше свободы, когда дело доходит до дополнительных сравнений.написав этот класс, вы можете использовать его так:

List<Post> posts = postsFromDatabase.Distinct(new PostComparer()).ToList();
5 голосов
/ 16 декабря 2011

Я думаю, что написать свой собственный компаратор - это хороший подход.

Вот статья в MSDN, которая очень хорошо объясняет тему: http://support.microsoft.com/kb/320727

Причина, по которой Distinct не работает, в том, что Distinct () не имеет представления о том, как определить, есть ли равные, поэтому он использует ссылку, чтобы определить, что это тот же самый "объект". Он работает так, как будто он готов к работе. Все классы в запросе не являются одним и тем же объектом.

Написав свой собственный компаратор (это легко), вы можете указать Distinct (), как выполнить сравнение, чтобы определить, равны ли они.

Редактировать : Если не использовать Distinct, это не проблема, и ситуация не частая, первый ответ Петра Юстины - это просто и эффективно.

1 голос
/ 16 декабря 2011

вместо .First (), попробуйте .FirstOrDefault ()

...