LINQ to SQL: distinct comparer

Оператор distinct, позволяющий производить выборки по уникальным записям и полям, широко используется во всех базах данных, реализующих наречия языка SQL. В LINQ to SQL метод Distinct также присутствует.

По умолчанию метод Distinct в LINQ to SQL выбирает из набора уникальные записи целиком, что бывает неудобно в случаях, когда требуется уникальность лишь по одному полю записи. Рассмотрим такой случай.

Предположим, что имеется таблица (сущностным классом которой является DBTable1) с двумя столбцами — Column1 и Column2 с произвольными данными. Из таблицы необходимо выбрать все строки, в которых содержимое первого столбца будет уникально. В случае использования обычного Distinct результатом выборки будут строки с уникальными Column1 и Column2. Для решения задачи требуется перегруженный вариант Distinct с использованием IEqualityComparer.

Реализация класса, наследующего интерфейс IEqualityComparer:
public class MyComparer : IEqualityComparer<DBTable1>
{
public bool Equals(
DBTable1 x, DBTable1 y)
{
return (x.Column1 == y.Column1);
}

public int GetHashCode(
DBTable1 obj)
{
return obj.Column1.GetHashCode();
}
}

Меняя реализацию метода Equals можно добиться сравнения по любым параметрам и их сочетаниям.

Применение описанного класса для выборки с использованием Distinct может выглядить так:
IEnumerable<DBTable1> s1 = db.DBTable1.ToList().Distinct(new MyComparer());

Замечание. Метод ToList() использован в примере неслучайно, а для преобразования выборки из IQueryable в IEnumerable. Использование описанного подхода для IQueryable генерирует исключение.
 
 

Статьи на схожую тематику:

.NET и не только: любите www.codeproject.com
Linq to SQL: количество строк в LinqDataSource
LINQ to SQL: select random или выборка случайных записей
LINQ to SQL: DeleteAllOnSubmit — удаляем быстро