Что именно представляет собой «информация», которую кэширует дэппер? - PullRequest
6 голосов
/ 28 марта 2012

На найденной документации Dapper здесь указано:

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

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

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

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

1 Ответ

9 голосов
/ 29 марта 2012

Насколько я знаю, каждый запрос выдает 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>();

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

...