У меня в базе есть несколько колокольчиков с таким же номером. Я хочу получить их все без дублирования. Я создал класс сравнения для выполнения этой работы, но выполнение функции вызывает большую задержку от функции без различия, от 0,6 до 3,2 секунды!
Правильно ли я делаю или мне нужно использовать другой метод?
reg.AddRange(
(from a in this.dataContext.reglements
join b in this.dataContext.Clients on a.Id_client equals b.Id
where a.date_v <= datefin && a.date_v >= datedeb
where a.Id_client == b.Id
orderby a.date_v descending
select new Class_reglement
{
nom = b.Nom,
code = b.code,
Numf = a.Numf,
})
.AsEnumerable()
.Distinct(new Compare())
.ToList());
class Compare : IEqualityComparer<Class_reglement>
{
public bool Equals(Class_reglement x, Class_reglement y)
{
if (x.Numf == y.Numf)
{
return true;
}
else { return false; }
}
public int GetHashCode(Class_reglement codeh)
{
return 0;
}
}
c#
linq
iequalitycomparer
Акрем
источник
источник
Ответы:
Ваша
GetHashCode
реализация всегда возвращает одно и то же значение.Distinct
полагается на хорошую хеш-функцию для эффективной работы, потому что она внутренне создает хеш-таблицу .При реализации интерфейсов классов важно читать документацию , чтобы знать, какой контракт вы должны реализовать. 1
В вашем коде решение состоит в том, чтобы переслать
GetHashCode
егоClass_reglement.Numf.GetHashCode
и соответствующим образом реализовать там.Кроме того, ваш
Equals
метод полон ненужного кода. Его можно было бы переписать следующим образом (семантика та же, ¼ кода, более читабельно):Наконец,
ToList
вызов является ненужным и занимает много времени:AddRange
принимает любой,IEnumerable
поэтому преобразование в aList
не требуется.AsEnumerable
здесь также является избыточным, поскольку обработка результата вAddRange
любом случае вызовет это.1 Написание кода, не зная, что он на самом деле делает, называется программированием культа карго . Это удивительно распространенная практика. Принципиально не работает.
источник
GetHashCode
. Однако обратите внимание, что в документацииIEqualityComparer<T>
не указано, что делать сnull
аргументами, но примеры, приведенные в статье, также не обрабатываютсяnull
.Попробуйте этот код:
Примером его использования может быть
источник
GetHashCode
также необходимо использовать это выражение:return _expr.Invoke(obj).GetHashCode();
см. этот пост, чтобы узнать его использование.Просто код с реализацией
GetHashCode
иNULL
проверкой:Пример: список Class_reglement, отличный от Numf
источник
Включение вашего класса сравнения (или, точнее,
AsEnumerable
вызова, который вам нужно было использовать, чтобы заставить его работать), означало, что логика сортировки перешла от основанной на сервере базы данных к клиенту базы данных (вашему приложению). Это означало, что теперь вашему клиенту необходимо получить, а затем обработать большее количество записей, что всегда будет менее эффективным, чем выполнение поиска в базе данных, где можно использовать соответствующие индексы.Вместо этого вам следует попытаться разработать предложение where, которое удовлетворяет вашим требованиям. Дополнительные сведения см. В разделе Использование IEqualityComparer с предложением LINQ to Entities Except .
источник
Если вам нужно универсальное решение без бокса:
использование:
источник
IEquatable<T>
может быть гораздо более простым способом сделать это с помощью современных фреймворков.Вы получаете красивую простую
bool Equals(T other)
функцию, и вам не придется возиться с приведением типов или созданием отдельного класса.Обратите внимание, что вам НЕОБХОДИМО реализовать,
GetHashCode
если вы используете это в словаре или с чем-то вродеDistinct
.PS. Я не думаю, что какие-либо пользовательские методы Equals работают со структурой сущностей непосредственно на стороне базы данных (я думаю, вы знаете это, потому что используете AsEnumerable), но это гораздо более простой метод для выполнения простых Equals для общего случая.
Если что-то не работает (например, повторяющиеся ключевые ошибки при выполнении ToDictionary), поместите точку останова внутри Equals, чтобы убедиться, что она попала, и убедитесь, что вы
GetHashCode
определили (с ключевым словом override).источник
.Equals()
методом вы , как представляется, по сравнениюother.Hometown
с собой, аthis.Hometown