Каков наилучший способ загрузки повторно используемых данных в веб-приложение .net
-
09-06-2019 - |
Вопрос
Допустим, у меня есть список категорий для навигации в веб-приложении.Вместо того, чтобы выбирать из базы данных для каждого пользователя, должен ли я добавить вызов функции в Application_OnStart глобального.asax для извлечения этих данных в массив или коллекцию, которые повторно используются снова и снова.Если мои данные вообще не меняются (Редактируются - очень часто), будет ли это лучшим способом?
Решение
Вы можете сохранить элементы списка в объекте Приложения.Вы правы насчет application_onStart()
, просто вызовите метод, который прочитает вашу базу данных и загрузит данные в объект приложения.
В Global.asax
public class Global : System.Web.HttpApplication
{
// The key to use in the rest of the web site to retrieve the list
public const string ListItemKey = "MyListItemKey";
// a class to hold your actual values. This can be use with databinding
public class NameValuePair
{
public string Name{get;set;}
public string Value{get;set;}
public NameValuePair(string Name, string Value)
{
this.Name = Name;
this.Value = Value;
}
}
protected void Application_Start(object sender, EventArgs e)
{
InitializeApplicationVariables();
}
protected void InitializeApplicationVariables()
{
List<NameValuePair> listItems = new List<NameValuePair>();
// replace the following code with your data access code and fill in the collection
listItems.Add( new NameValuePair("Item1", "1"));
listItems.Add( new NameValuePair("Item2", "2"));
listItems.Add( new NameValuePair("Item3", "3"));
// load it in the application object
Application[ListItemKey] = listItems;
}
}
Теперь вы можете получить доступ к своему списку в остальной части проекта.Например, в default.aspx для загрузки значений в выпадающий список:
<asp:DropDownList runat="server" ID="ddList" DataTextField="Name" DataValueField="Value"></asp:DropDownList>
И в файле с исходным кодом:
protected override void OnPreInit(EventArgs e)
{
ddList.DataSource = Application[Global.ListItemKey];
ddList.DataBind();
base.OnPreInit(e);
}
Другие советы
Если он никогда не меняется, то, вероятно, ему не обязательно быть в базе данных.
Если данных немного, вы можете поместить их в web.config или в виде Enum в вашем коде.
Извлечение всего этого может обойтись дорого.Попробуйте lazy init, извлеките только данные запроса, а затем сохраните их в переменной кэша.
Преждевременная оптимизация - это зло.Это само собой разумеющееся, если у вас возникли проблемы с производительностью в вашем приложении и у вас есть "статическая" информация, которую вы хотите отобразить своим пользователям, вы определенно можете загрузить эти данные один раз в массив и сохранить их в объекте приложения.Вы хотите быть осторожными и сбалансировать использование памяти с оптимизацией.
Проблема, с которой вы сталкиваетесь, заключается в изменении информации, хранящейся в базе данных, и в том, что она не обновляет кэшированную версию.Вероятно, вы хотели бы иметь какую-то дату последнего изменения в базе данных, которую вы храните в состоянии вместе с кэшированными данными.Таким образом, вы можете запросить время наибольшего изменения и сравнить его.Если он более новый, чем ваша кэшированная дата, вы сбрасываете его и перезагружаете.
В переменной приложения.
Помните, что переменная приложения может содержать объект в .Net, поэтому вы можете создать экземпляр объекта в global.asax, а затем использовать его непосредственно в коде.
Поскольку переменные приложения находятся в памяти, они выполняются очень быстро (по сравнению с необходимостью вызова базы данных).
Например:
// Create and load the profile object
x_siteprofile thisprofile = new x_siteprofile(Server.MapPath(String.Concat(config.Path, "templates/")));
Application.Add("SiteProfileX", thisprofile);
Я бы сохранил данные в кэше приложения (Cache object).И я бы не стал загружать его предварительно, я бы загрузил его при первом запросе.Что приятно в кэше, так это то, что ASP.NET будет управлять им, включая предоставление вам опций истечения срока действия записи в кэше после изменения файла, периода времени и т.д.И поскольку элементы хранятся в памяти, объекты не сериализуются / десериализуются, поэтому использование происходит очень быстро.
Использование очень простое.В объекте Cache существуют методы Get и Add для извлечения и добавления элементов в кэш соответственно.
Я использую статическую коллекцию как закрытую с общедоступным статическим свойством, которое либо загружает, либо получает ее из базы данных.
Кроме того, вы можете добавить статическое datetime, которое устанавливается при загрузке, и если вы вызываете его по истечении определенного промежутка времени, очистите статическую коллекцию и запросите ее.
Кэширование - это правильный путь.И если вам нравятся шаблоны проектирования, взгляните на синглтон.
Однако в целом я не уверен, что стал бы беспокоиться по этому поводу, пока вы не заметите снижение производительности.