Hashset vs. IQueryable - PullRequest
       23

Hashset vs. IQueryable

5 голосов
/ 25 февраля 2010

Недавно я работал над реализацией небольшого фрагмента, который кэширует мои результаты, и то, как я это делал, использовал словарь следующим образом:

 private Dictionary<ID, IQueryable<Results>> _simpleCache;

Идея состояла в том, чтобы найти все результаты с идентификатором, указанным в «ID», и, если в словаре содержится ключ == id, мы просто ищем значения, присутствующие в IQueryable, вместо того, чтобы выполнять отключение базы данных.

Сегодня утром я рассматривал эту логику и думал о замене IQueryable на HashSet следующим образом:

private Dictionary<ID, HashSet<Results>> _simpleCache;

Желательно ли сделать это изменение?

1 Ответ

13 голосов
/ 25 февраля 2010

Да, это так. Как правило, IQueryable<T> подразумевает, что вы используете провайдера источника данных, который запрашивается при каждом перечислении запрашиваемого (конечно, это не всегда случай, как вы можете Вызовите AsQueryable метод расширения для IEnumerable<T>, который даст вам реализацию IQueryable<T> по сравнению с реализацией IEnumerable<T>).

С этой целью сохранение IQueryable<Results> в словаре фактически не предотвращает попадания в источник данных, когда вы просматриваете его во второй раз. Он будет запрашивать у поставщика данных каждый раз, когда вы будете через него перечислять.

Из-за этого вы обычно хотите реализовать результаты на стороне клиента, обычно вызывая методы расширения ToList или ToArray, а затем используя IEnumerable<Results> или Results[] в качестве параметра типа TValue вашего словаря.

Обратите внимание, что вы могли бы использовать HashSet<T> для хранения своих объектов, но вы должны убедиться, что вы реализовали IEquatable<T> и переопределили GetHashCode, чтобы компаратор равенства по умолчанию выполнял сравнение для экземпляра ID, представленного типом Results, либо вам нужно предоставить IEqualityComparer<T> реализация, которая будет делать то же самое. Скорее всего, вы используете сгенерированный дизайнером код, и он не сделает этого за вас, и ваши объекты будут иметь равенство, определяемое по ссылке, а не по значению.

...