Какую именно информацию кеширует dapper?

В документации Dapper, найденной здесь, говорится:

Ограничения и предостережения

Dapper кэширует информацию о каждом выполняемом запросе, что позволяет ему быстро материализовать объекты и быстро обрабатывать параметры . Текущая реализация кэширует эту информацию в объекте ConcurrentDictionary.

Что именно это означает? Пример: это кеширование возвращаемых данных, или самого запроса, или битов того и другого?

Также говорится, что эти [кэшированные] данные никогда не сбрасываются. Как это повлияет на кэшированную информацию, если схема проектирования запрашиваемой таблицы (таблиц) изменится?


person JCisar    schedule 27.03.2012    source источник


Ответы (1)


Насколько я знаю, каждый запрос выдает Identity, в зависимости от запроса sql, его типа команды и его параметров. Кэш — это словарь с одновременным доступом.

Dictionary<Identity, CacheInfo> _queryCache

Этот объект CacheInfo содержит функции IDataReader и IDBCommand, а также некоторые контрольные счетчики, которые ограничивают кэшируемый объем.

Поскольку никакая серверная сторона (схема базы данных и т. д.) не кэшируется, на самом деле это не имеет никакого влияния.

Изменить: вот как выглядит класс Identity, используемый для кэширования.

private Identity(string sql, CommandType? commandType, string connectionString, Type type, Type parametersType, Type[] otherTypes, int gridIndex)
        {
            this.sql = sql;
            this.commandType = commandType;
            this.connectionString = connectionString;
            this.type = type;
            this.parametersType = parametersType;
            this.gridIndex = gridIndex;
            unchecked
            {
                hashCode = 17; // we *know* we are using this in a dictionary, so pre-compute this
                hashCode = hashCode * 23 + commandType.GetHashCode();
                hashCode = hashCode * 23 + gridIndex.GetHashCode();
                hashCode = hashCode * 23 + (sql == null ? 0 : sql.GetHashCode());
                hashCode = hashCode * 23 + (type == null ? 0 : type.GetHashCode());
                if (otherTypes != null)
                {
                    foreach (var t in otherTypes)
                    {
                        hashCode = hashCode * 23 + (t == null ? 0 : t.GetHashCode());
                    }
                }
                hashCode = hashCode * 23 + (connectionString == null ? 0 : connectionString.GetHashCode());
                hashCode = hashCode * 23 + (parametersType == null ? 0 : parametersType.GetHashCode());
            }
        }

А вот CacheInfo

class CacheInfo

        {
            public Func<IDataReader, object> Deserializer { get; set; }
            public Func<IDataReader, object>[] OtherDeserializers { get; set; }
            public Action<IDbCommand, object> ParamReader { get; set; }
            private int hitCount;
            public int GetHitCount() { return Interlocked.CompareExchange(ref hitCount, 0, 0); }
            public void RecordHit() { Interlocked.Increment(ref hitCount); }
        }

И, наконец, контейнер тайника.

static readonly System.Collections.Concurrent.ConcurrentDictionary<Identity, CacheInfo> _queryCache = new System.Collections.Concurrent.ConcurrentDictionary<Identity, CacheInfo>();

Взгляните на исходный код, он очень хорошо написан и прост в отслеживании/отладке. Просто перетащите файл в свой проект.

person Alex    schedule 29.03.2012