Как я могу кэшировать функцию в asp.net - PullRequest
1 голос
/ 02 марта 2010

У меня есть функция, которая рассчитывает расстояние от записей базы данных. Эта функция вызывается как минимум дважды в одном запросе страницы asp.net. В этот период времени результат не меняется. Итак, что нужно сделать для кэширования результата, мне нужна производительность в моем приложении.

Например:

public static int GetKilometers(int VehicleID)
{ /*some db query and calculations*/ }

Ответы [ 5 ]

2 голосов
/ 02 марта 2010

Если вас беспокоит только результат за время жизни одного запроса страницы (как вы упомянули в своем вопросе), будет достаточно простой локальной переменной:

private int? _dist;

public int GetKilometers(int VehicleID)
{ 
    if (_dist == null) {
        _dist = /*some db query and calculations*/ 
    }
    return _dist;
}

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

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

1 голос
/ 02 марта 2010

Из вопроса ОП все эти ответы полезны, и синтаксис тот же, но используются неправильные коллекции. Подходящая коллекция для этого - HttpContext.Current.Items. Объедините это с ответом от @ Aaron

1 голос
/ 02 марта 2010

Для быстрого и простого решения вы можете использовать объект HttpContext.Session для хранения значения, подобного этому:

int distance;
if(Session["distance"] == null)
{
    distance = GetKilometers(vehicleId);
    Session["distance"] = distance;
}
else
{
    distance = Convert.ToInt32(Session["distance"]);
}

Чтобы сделать это еще проще, вы можете абстрагировать это в свой собственный метод.

EDIT

Приведенное выше решение подходит для минимального объема данных. Учитывая тот факт, что в вашем случае будет храниться МНОГО данных, я вижу два возможных сценария:

Расчетные данные для транспортного средства X различны для каждого пользователя
Кэшируйте вычисленные данные в отдельной таблице в базе данных с помощью UserId (или SessionId), VehicleId и CalculatedData.

Расчетные данные для транспортного средства X одинаковы для любого пользователя, которому нужны данные транспортного средства X
Кэш, который рассчитал данные в столбце таблицы транспортных средств в базе данных.

В любом случае, ваш вызов в базу данных должен получить данные для всех транспортных средств, которые нужны пользователю для текущего запроса. Затем сохраните эти данные в локальной переменной, которая живет только для текущего запроса. Если вы собираетесь кэшировать данные по сеансам, вы можете использовать HttpContext.Session для хранения SessionId и использовать его для извлечения данных из базы данных.

0 голосов
/ 02 марта 2010

Если будет так много вычислений, то использование Session израсходует память вашего сервера. Вы можете использовать ViewState, но это сделает вашу страницу довольно тяжелой.

Можно ли не попасть в БД? Или свести к минимуму количество поездок в БД.

Что-то вроде:

public static int GetKilometer (int [] VehicleID) {/ * получить все данные за один раз * /}

0 голосов
/ 02 марта 2010

сохранить в сеансе с условием if, если оно определенно не изменяется

if(Session["functionresult"] == null)
{
    Session["functionresult"] = functionResult;
}
...