2008-09-15 13 views
2

Sagen wir, ich habe eine Liste von Kategorien für die Navigation in einer Web-App. Anstatt in der Datenbank für jeden Benutzer auszuwählen, sollte ich einen Funktionsaufruf in application_onStart der Datei global.asax hinzufügen, um diese Daten in ein Array oder eine Sammlung abzurufen, die immer wieder verwendet werden. Wenn sich meine Daten gar nicht ändern - (Edit - sehr oft), wäre das der beste Weg?Was ist der beste Weg, stark wiederverwendet Daten in einer .net Web-Anwendung zu laden

+0

Ich würde vorschlagen, jemand mit genügend Rep sollte dies mit "Caching" Tag ... – rohancragg

Antwort

2

Sie die Listenelemente in das Application-Objekt speichern kann. Sie haben recht mit der application_onStart(), rufen Sie einfach eine Methode auf, die Ihre Datenbank liest und die Daten in das Application-Objekt lädt.

In 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; 
    } 
} 

Jetzt können Sie Ihre Liste im Rest des Projekts zugreifen. Zum Beispiel in default.aspx die Werte in einer Dropdownlist laden:

<asp:DropDownList runat="server" ID="ddList" DataTextField="Name" DataValueField="Value"></asp:DropDownList> 

Und in der Code-Behind-Datei:

protected override void OnPreInit(EventArgs e) 
{ 
    ddList.DataSource = Application[Global.ListItemKey]; 
    ddList.DataBind(); 
    base.OnPreInit(e); 
} 
+0

Schöne Lösung mit Codebeispiel - Prost. Ich würde sagen, das ist sehr nahe an dem, wonach ich suche. – Mike

0

Ich verwende eine statische Sammlung als private mit einer öffentlichen statischen Eigenschaft, die es entweder lädt oder aus der Datenbank holt.

Zusätzlich können Sie eine statische datetime hinzufügen, die gesetzt wird, wenn es geladen wird, und wenn Sie es für eine bestimmte Zeit aufrufen, löschen Sie die statische Auflistung und requery es.

1

Wenn es sich nie ändert, muss es wahrscheinlich nicht in der Datenbank sein.

Wenn nicht viele Daten vorhanden sind, können Sie sie in die Datei web.config oder als enum in Ihren Code einfügen.

+0

Guter Punkt. Die Daten können sich ändern und ich war nicht klar in der Frage, also habe ich es aktualisiert. Es tut uns leid. – Mike

1

Abrufen aller kann teuer werden. Versuchen Sie fazy init, holen Sie nur request-Daten und speichern Sie sie dann in der Cache-Variable.

1

Vorzeitige Optimierung ist böse. Wenn Sie in Ihrer Anwendung Leistungsprobleme haben und "statische" Informationen haben, die Sie Ihren Benutzern anzeigen möchten, können Sie diese Daten definitiv einmal in ein Array laden und im Anwendungsobjekt speichern. Sie möchten vorsichtig sein und die Speichernutzung mit der Optimierung ausgleichen.

Das Problem, das Sie dann ausführen, ist das Ändern der gespeicherten Informationen der Datenbank und nicht das Aktualisieren der zwischengespeicherten Version. Wahrscheinlich möchten Sie in der Datenbank, die Sie zusammen mit den zwischengespeicherten Daten im Status speichern, ein Datum ändern, das zuletzt geändert wurde. Auf diese Weise können Sie die größte veränderte Zeit abfragen und vergleichen. Wenn es neuer als das zwischengespeicherte Datum ist, dann wird es gelöscht und erneut geladen.

+0

Super Punkt! Derzeit gibt es keine Probleme. Ich schnüffle herum und suche nach Engpässen, wenn die Sessions schnell ansteigen - aka der Slashdot/Digg/Reddit-Effekt. Das Problem beim erneuten Laden könnte eine andere Frage sein. – Mike

1

In einer Anwendungsvariablen.

Denken Sie daran, dass eine Anwendungsvariable ein Objekt in .Net enthalten kann, sodass Sie das Objekt in der Datei global.asax instanziieren und dann direkt im Code verwenden können.

Da Anwendungsvariablen im Speicher sind, sind sie sehr schnell (vs eine Datenbank aufrufen zu müssen)

Zum Beispiel:

// Create and load the profile object 
x_siteprofile thisprofile = new x_siteprofile(Server.MapPath(String.Concat(config.Path, "templates/"))); 
Application.Add("SiteProfileX", thisprofile); 
1

Ich würde die Daten in der Application Cache (Cache-Objekt) speichern . Und ich würde es nicht vorladen, ich würde es laden, wenn es das erste Mal angefordert wird. Was am Cache schön ist, ist dieser ASP.NET wird es verwalten, einschließlich Optionen für das Verfallen des Cache-Eintrags nach Dateiänderungen, einem Zeitraum, usw. Und da die Elemente im Speicher gehalten werden, werden die Objekte nicht serialisiert/deserialisiert, so dass die Verwendung sehr schnell ist.

Die Verwendung ist unkompliziert. Es gibt Methoden Get und Add für das Cache-Objekt, um Elemente zum Cache abzurufen bzw. hinzuzufügen.

+0

Jeff - Großer Vorschlag. Ich hatte einige Probleme mit dem Web-Caching, da alles andere auf der Seite dynamisch ist, sogar der Header. Ich bin davon weggeblieben, da ich jedes Mal eine neue Kopie möchte, also mag ich die App-Route. Was auch immer im Monat angeboten wird - bequemer Auffrischung ist am besten. – Mike

0

Caching ist der Weg zu gehen. Und wenn Sie in Design-Muster, werfen Sie einen Blick auf das Singleton.

Insgesamt bin ich mir jedoch nicht sicher, ob ich mir Sorgen machen würde, bis Sie Leistungseinbußen feststellen.