Недавно я работал над реализацией маленького отрывка, который кэширует мои результаты и способ, которым я делал, это использовало Словарь следующим образом:
private Dictionary<ID, IQueryable<Results>> _simpleCache;
Идея состояла в том, чтобы искать все результаты, которым указал идентификатор 'идентификатор' и если Словарь содержит ключ == идентификатор, мы просто перерываем значения, существующие в IQueryable вместо того, чтобы совершить поездку базы данных.
Я пробегался через эту часть логики этим утром, и я думал о замене IQueryable с HashSet следующим образом:
private Dictionary<ID, HashSet<Results>> _simpleCache;
Делает это изменение желательным?
Да, это так. Как правило, IQueryable
подразумевает, что вы используете поставщика источника данных, который запрашивается каждый раз при перечислении запрашиваемого объекта (конечно, это не всегда случай, как вы может вызвать метод расширения AsQueryable в IEnumerable
, что даст вам реализацию IQueryable
поверх IEnumerable
выполнение).
С этой целью сохранение IQueryable
в словаре фактически не предотвращает попадания в источник данных при повторной нумерации. Он будет делать запрос поставщику данных каждый раз, когда вы выполняете перечисление через него.
Из-за этого вы обычно хотите материализовать результаты на стороне клиента, обычно вызывая методы расширения ToList
или ToArray
, а затем используя IEnumerable
или Результаты []
в качестве параметра типа TValue
вашего словаря.
Обратите внимание, что вы можете использовать HashSet
для хранения ваших объектов, но вы должны убедиться, что вы реализуете IEquatable
и переопределить GetHashCode
, чтобы компаратор проверки на равенство по умолчанию выполнял сравнение экземпляра ID
, предоставленного типом Results
, либо это, либо вы должны предоставить IEqualityComparer
, которая будет делать то же самое.Более чем вероятно, что вы используете код, созданный дизайнером, и он не сделает этого за вас, и ваши объекты будут иметь равенство, определяемое ссылкой, а не значением.