Кэширование данных из DataContext - PullRequest
4 голосов
/ 16 мая 2011

Мы используем Linq-to-SQL DataContext в веб-приложении, которое предоставляет приложению данные только для чтения и никогда не обновляется (для обеспечения этого установите ObjectTrackingEnabled = false.

Поскольку данныеникогда не меняется (за исключением периодических обновлений конфигурации), кажется расточительным перезагружать его из SQL Server с новым DataContext для каждого веб-запроса.

Мы пытались кэшировать DataContext в объекте Application для всех запросов на использование, ноэто породило много ошибок, и наше исследование показывает, что это плохая идея, DataContext должен быть удален в пределах одной и той же единицы работы, а не потокобезопасен и т. д. и т. д.

Так как DataContext являетсянамеревался быть механизмом доступа к данным, а не хранилищем данных, нам нужно смотреть на кэширование данных, которые мы получаем из него, а не на сам контекст.

Предпочел бы делать это с самими сущностями и коллекциями.поэтому код может не зависеть от того, имеет ли он дело с кэшированными или «свежими» данными.

Как это можно сделать безопасно?

Во-первых, мне нужно убедиться, что сущности и коллекции полностью загружены, прежде чем я избавлюсь от DataContext.Есть ли способ для удобной принудительной полной загрузки всего из базы данных?

Во-вторых, я вполне уверен, что хранение ссылок на сущности и коллекции - плохая идея, потому что это будет либо

(a) вызывает повреждение объектов, когда DataContext выходит из области видимости или

(b) предотвращает выход DataContext из области действия

Поэтому я должен клонировать EntitySets и сохранитьих?Если так, то как?Или что здесь?

Ответы [ 2 ]

1 голос
/ 16 мая 2011

Это не совсем ответ на ваш вопрос, но я предлагаю избегать кеширования на стороне веб-сайта.
Я бы лучше сосредоточился на оптимизации запросов к базе данных для более быстрого и более эффективного поиска данных.

Кэширование:

  • не будет масштабируемым
  • нужен дополнительный код для синхронизации, я предполагаю, что ваши данные не полностью статичны в БД?
  • дополнительный код будетподверженные ошибкам
  • быстро израсходует память вашего веб-сервера, следующая вещь, к которой вы можете обратиться, - проблема с памятью на вашем веб-сервере
  • не будет работать очень хорошо, когда вам нужно загрузить-балансировать ваш веб-сайт

[Редактировать]

Если бы мне нужно было кэшировать данные 5 МБ, я бы использовал объект Cache , вероятнос ленивой загрузкой.Я бы использовал набор легких коллекций, таких как ReadonlyCollection<T>, Collectino<T>.Я бы, вероятно, использовал ReadonlyDictionary<TKey, TValue> также для быстрого поиска в памяти.Я бы использовал LINQ-to-Objects для манипулирования коллекциями.

0 голосов
/ 16 мая 2011

Вы хотите кэшировать данные, извлеченные из DataContext, а не сам объект DataContext.Я обычно реорганизую обычные извлеченные данные в методы, с помощью которых я могу реализовать тихое кэширование, что-то вроде этого (может потребоваться добавить поточно-ориентированную логику):

public class MyBusinssLayer {

    private List<MyType> _myTypeCache = null;
    public static List<MyType> GetMyTypeList() {
        if (_myTypeCache == null) {
            _myTypeCache = // data retrieved from SQL server
        }

        return _myTypeCache
    }

}

Это самый простой шаблон, который можно использоватьи будет кешировать для одного веб-запроса.Для кэширования на более длительные периоды храните содержимое в долговременном хранилище, например Application или Cache.Например, для хранения данных уровня Application используйте этот тип шаблона.

public static List<MyType> GetMyTypeList() {
    if (Application["MyTypeCacheName"] = null) {
        Application["MyTypeCacheName"] = // data retrieved from SQL server
    }

    return (List<MyType>)Application["MyTypeCacheName"];
}

Это будет для данных, которые почти никогда не изменяются, таких как статическая коллекция типов состояний, которые можно выбрать вDropDownList.Для получения более изменчивых данных вы можете использовать Cache с периодом ожидания, который следует выбирать в зависимости от частоты изменения данных.С помощью Cache элементы могут быть аннулированы вручную с помощью кода, если необходимо, или с помощью средства проверки зависимостей, например SqlCacheDependency.

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...