2010-05-25 14 views
5

Ho una classe che memorizza i dati nell'applicazione asp.net C# che non cambia mai. Non voglio davvero mettere questi dati nel database - mi piacerebbe che restasse nell'applicazione. Ecco il mio modo di memorizzare i dati nell'applicazione:Qual è il modo migliore per archiviare dati statici in C# che non cambierà mai

public class PostVoteTypeFunctions 
{ 
    private List<PostVoteType> postVotes = new List<PostVoteType>(); 
    public PostVoteTypeFunctions() 
    { 
     PostVoteType upvote = new PostVoteType(); 
     upvote.ID = 0; 
     upvote.Name = "UpVote"; 
     upvote.PointValue = PostVotePointValue.UpVote; 
     postVotes.Add(upvote); 

     PostVoteType downvote = new PostVoteType(); 
     downvote.ID = 1; 
     downvote.Name = "DownVote"; 
     downvote.PointValue = PostVotePointValue.DownVote; 
     postVotes.Add(downvote); 

     PostVoteType selectanswer = new PostVoteType(); 
     selectanswer.ID = 2; 
     selectanswer.Name = "SelectAnswer"; 
     selectanswer.PointValue = PostVotePointValue.SelectAnswer; 
     postVotes.Add(selectanswer); 

     PostVoteType favorite = new PostVoteType(); 
     favorite.ID = 3; 
     favorite.Name = "Favorite"; 
     favorite.PointValue = PostVotePointValue.Favorite; 
     postVotes.Add(favorite); 

     PostVoteType offensive = new PostVoteType(); 
     offensive.ID = 4; 
     offensive.Name = "Offensive"; 
     offensive.PointValue = PostVotePointValue.Offensive; 
     postVotes.Add(offensive); 

     PostVoteType spam = new PostVoteType(); 
     spam.ID = 0; 
     spam.Name = "Spam"; 
     spam.PointValue = PostVotePointValue.Spam; 
     postVotes.Add(spam); 
    } 
} 

Quando viene chiamato il costruttore, viene eseguito il codice sopra. Ho alcune funzioni che possono interrogare anche i dati sopra. Ma è questo il modo migliore per archiviare informazioni in asp.net? se no cosa consiglieresti?

risposta

3

Questo è un candidato per uno struct immutabile che "sembra" un'enumerazione: (Inoltre, ho notato che hai usato lo stesso valore id per due di loro, in modo da mi fisso che ... È possibile utilizzare il seguente proprio come si farebbe con un'enumerazione ...

PostVoteTypeFunctions myVar = PostVoteTypeFunctions.UpVote; 

e reale cosa bella è che questo approccio non richiede memorizzazione esempio diverso da un numero intero di 4 byte (che saranno memorizzati sulla pila, in quanto si tratta di un struct). Tutti i valori hardcoded sono memorizzati nel tipo stesso ... di cui ne esiste uno solo per AppDomain ...

public struct PostVoteTypeFunctions 
{ 
    private int id; 
    private bool isDef; 
    private PostVoteTypeFunctions () { } // private to prevent direct instantiation 
    private PostVoteTypeFunctions(int value) { id=value; isDef = true; } 

    public bool HasValue { get { return isDef; } } 
    public bool isNull{ get { return !isDef; } } 
    public string Name 
    { 
     get 
     { return 
      id==1? "UpVote": 
      id==2? "DownVote": 
      id==3? "SelectAnswer": 
      id==4? "Favorite": 
      id==5? "Offensive": 
      id==6? "Spam": "UnSpecified"; 
     } 
    } 
    public int PointValue 
    { 
     get 
     { return // Why not hard code these values here as well ? 
      id==1? PostVotePointValue.UpVote: 
      id==2? PostVotePointValue.DownVote 
      id==3? PostVotePointValue.SelectAnswer: 
      id==4? PostVotePointValue.Favorite: 
      id==5? PostVotePointValue.Offensive: 
      id==6? PostVotePointValue.Spam: 
        0; 
     } 
    } 
    // Here Add additional property values as property getters 
    // with appropriate hardcoded return values using above pattern 

    // following region is the static factories that create your instances, 
    // .. in a way such that using them appears like using an enumeration 
    public static PostVoteTypeFunctions UpVote = new PostVoteTypeFunctions(1); 
    public static PostVoteTypeFunctions DownVote= new PostVoteTypeFunctions(2); 
    public static PostVoteTypeFunctions SelectAnswer= new PostVoteTypeFunctions(3); 
    public static PostVoteTypeFunctions Favorite= new PostVoteTypeFunctions(4); 
    public static PostVoteTypeFunctions Offensive= new PostVoteTypeFunctions(5); 
    public static PostVoteTypeFunctions Spam= new PostVoteTypeFunctions(0);  
} 
+0

Sospetto che una semplice istruzione switch/case possa, in media, fornire prestazioni leggermente migliori e sarebbe più leggibile rispetto all'uso di operatori ternari concatenati. –

+0

Questo può funzionare anche meglio se si definisce un'enumerazione privata nidificata all'interno della definizione struct e si sostituisce il campo int con esso. In alternativa, definire un gruppo di costanti int all'interno della struttura in modo che i costruttori di numeri magici, ifs e casi di switch siano più leggibili. –

+0

@ Cameron, sul tuo suggerimento sull'uso degli switch. Non so sulle prestazioni (in genere, affronterò solo le prestazioni quando c'è un problema, ma per quanto riguarda la manutenibilità, leggibilità, estensibilità, ecc., I ternerys sono più concisi e sono quindi PIÙ leggibile, oltre che più estendibile (meno da modificare/duplicare) .Questo argomento è indirizzato in modo profuso in altri post su questo forum. –

0

Se non cambia, è comunemente utilizzato ed è lo stesso per tutti gli utenti, quindi la cache di .NET è la posizione corretta. Avere una proprietà che produce questi valori. All'interno, la proprietà controlla la cache per questo elenco e restituisce il valore memorizzato; altrimenti, lo costruisce da zero, aggiunge alla cache e restituisce il valore.

Questo dovrebbe comunque essere configurato nel database, anche se lo si memorizza nella cache. Immagino che dovrai usare questi valori insieme ad altri dati nel tuo DB.

1

È difficile capire dal frammento di codice che è stato pubblicato se si espongono i dati al di fuori della classe.

In caso contrario, funzionerebbe. Tuttavia, in caso contrario, ci sono diverse questioni:

  • Se si sta esponendo l'elenco, si dovrebbe sempre e solo restituire una copia di esso come un IEnumerable<PostVoteType> utilizzando la parola chiave yield.
  • Assicurarsi che il PostVoteType è immutabile, altrimenti i riferimenti possono essere cambiati ei campi utilizzati potrebbero essere alterati
1

"Mai" è una parola molto dura davvero.

Nel vostro caso particolare state affermando che non solo i vostri dati PostVoteType sono assoluti e immutabili, ma anche la raccolta di container. Francamente non credo che tu possa saperlo, perché non sei un business (la tua interpretazione del requisito è imperfetta) e non sei un sensitivo (la tua conoscenza del futuro è imperfetta).

Suggerirei di memorizzare sempre tutti i dati che non possono essere espressi come un'enumerazione in del tipo del repository. Dove ti aspetti esigenze relazionali e/o transazionali e/o mutabili che significano un database, se ti aspetti un elevato rapporto di lettura/scrittura che può essere un file di configurazione (che credo dovrebbe essere questo caso).

Modifica: In termini di persistenza della memoria sono d'accordo con gli altri che la cache è il posto migliore per archiviare questo, o meglio in un oggetto di dominio che è supportato dalla cache.


parte: la costruzione di PostVoteTypes è orribile - suggeriscono fortemente che si desidera un refactoring :)

+0

oh yay, downvotes random di nuovo – annakata

+0

Che cosa è orribile? Che refactoring consiglieresti? –

+5

Una delle peggiori non risposte che abbia mai visto in SO. Tu fai delle supposizioni sui requisiti aziendali e poi castighi la persona che pone la domanda basandosi sulle tue supposizioni non giustificate e sui pregiudizi ingiustificati. Quindi procedi a non dare alcun tipo di risposta. E nessun mio downvote non era casuale. –

0

Quando è necessario accedere spesso agli stessi dati e non è necessario memorizzarli nel database sottostante e questi dati sono pressoché uguali in tutte le situazioni che l'applicazione potrebbe incontrare, suggerisco di utilizzare la memorizzazione nella cache. Il caching nasce da questi requisiti.Il caching è normalmente il modo più veloce per fornire dati poiché vengono sempre conservati in memoria o qualcosa di simile per facilitare e rendere l'accesso più semplice dall'applicazione.

Ecco uno strumento di memorizzazione nella cache fornito con Microsoft Enterprise Library, Caching Application Block.

Penso che valga la pena prendersi del tempo per imparare come usarlo efficacemente.

1

Guardando il tuo codice, sembra che tu stia solo cercando di creare un insieme di oggetti che in realtà inseriscono l'enumerazione di PostVotePointValue in una sorta di elenco. Cioè hai già ciò che hai bisogno di definire nel solo enum stesso. Ti incoraggio a non definire le stesse informazioni in due punti (questo archivio dati che stai chiedendo e l'enumerazione). Questo è un errore comune che vedo le persone fare. Crea una tabella/lista di ricerca, quindi crea un enum che rispecchia le righe della tabella e ciò significa che devono modificare due posizioni per qualsiasi modifica all'elenco.

Se PostVotePointValue non è un enumerato ma solo alcune costanti o se ci sono più informazioni che si stanno pianificando di completare, allora questo non è rilevante.

Ecco alcuni esempi di come lavorare con enumerazioni come 'liste' dal http://www.csharp-station.com/Tutorials/Lesson17.aspx

// iterate through Volume enum by name 
    public void ListEnumMembersByName() 
    { 
     Console.WriteLine("\n---------------------------- "); 
     Console.WriteLine("Volume Enum Members by Name:"); 
     Console.WriteLine("----------------------------\n"); 

     // get a list of member names from Volume enum, 
     // figure out the numeric value, and display 
     foreach (string volume in Enum.GetNames(typeof(Volume))) 
     { 
      Console.WriteLine("Volume Member: {0}\n Value: {1}", 
       volume, (byte)Enum.Parse(typeof(Volume), volume)); 
     } 
    } 

    // iterate through Volume enum by value 
    public void ListEnumMembersByValue() 
    { 
     Console.WriteLine("\n----------------------------- "); 
     Console.WriteLine("Volume Enum Members by Value:"); 
     Console.WriteLine("-----------------------------\n"); 

     // get all values (numeric values) from the Volume 
     // enum type, figure out member name, and display 
     foreach (byte val in Enum.GetValues(typeof(Volume))) 
     { 
      Console.WriteLine("Volume Value: {0}\n Member: {1}", 
       val, Enum.GetName(typeof(Volume), val)); 
     } 
    } 
} 

si dovrebbe essere in grado di adattare il sopra in un approccio che vi darà una lista che è possibile utilizzare per l'associazione dati, se ne hai bisogno.

0

Mi chiedo perché non è possibile utilizzare una semplice enumerazione per questo?

public enum PostVoteType 
{ 
    UpVote = 0, 
    DownVote = 1, 
    SelectAnswer = 2, 
    Favorite = 3, 
    Offensize = 4, 
    Spam = 5 
} 
+0

Beh, se l'upvote vale 15 punti, come metterei il valore in punti nell'enum. È possibile? Per favore mi faccia sapere. Grazie – Luke101

+0

potresti sempre avere una lista statica e fare qualcosa di simile. var type = PostVoteType.UpVote; var points = new Dictionary (); var value = points [type]; –

Problemi correlati