2010-05-25 13 views
5

Tengo una clase que almacena datos en la aplicación asp.net C# que nunca cambia. Realmente no quiero poner esta información en la base de datos. Me gustaría que permanezca en la aplicación. Aquí está mi manera de almacenar los datos en la aplicación:Cuál es la mejor manera de almacenar datos estáticos en C# que nunca cambiará

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

Cuando se llama al constructor el código anterior se corrieron. Tengo algunas funciones que pueden consultar los datos anteriores también. Pero, ¿es esta la mejor forma de almacenar información en asp.net? si no, ¿qué recomendarías?

Respuesta

3

Este es un candidato para una estructura inmutable que "parece" una enumeración: (Además, me di utilizó el mismo valor de ID para dos de ellos, por lo que me fijo ... Usted puede utilizar el siguiente tal como lo haría una enumeración ...

PostVoteTypeFunctions myVar = PostVoteTypeFunctions.UpVote; 

y cosa agradable real es que este enfoque no requiere almacenamiento de instancia que no sea un número entero de 4 bytes (que se almacena en la pila, ya que es una struct). Todos los valores codificados se almacenan en el tipo en sí ... de los cuales solo existirá uno por 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

. Sospecho que una simple declaración de conmutador/caso, en promedio, proporcionaría un rendimiento ligeramente mejor y sería más legible que su uso de operadores ternarios encadenados. –

+0

Esto puede funcionar aún mejor si define una enumeración privada anidada dentro de la definición de estructura y reemplaza el campo int con ella. Alternativamente, defina un grupo de constantes int dentro de la estructura para que los constructores de números mágicos, los ifs y los casos de cambio sean más legibles. –

+0

@Cameron, la sugerencia sobre el uso de interruptores .. No sé sobre el rendimiento (en general, solo me refiero al rendimiento cuando hay un problema, pero en términos de facilidad de mantenimiento, legibilidad, extensibilidad, etc., los Ternerys son más concisos, y por lo tanto, MÁS legible, y más extensible (menos para modificar/duplicar). Este tema se aborda profusamente en otras publicaciones de este foro. –

0

Si no cambia, se accede comúnmente, y es el mismo para todos los usuarios, entonces el caché .NET es el lugar correcto. Tener una propiedad que produzca estos valores. En el interior, la propiedad verifica la caché para esta lista y devuelve el valor almacenado; de lo contrario, lo construye desde cero, agrega al caché y devuelve el valor.

Sin embargo, esto aún debería configurarse en la base de datos, incluso si lo almacena en caché. Imagino que necesitará usar estos valores junto con otros datos en su base de datos.

1

Es difícil saber a partir del fragmento de código que ha publicado si expone cualquiera de los datos fuera de la clase.

Si no, entonces esto funcionaría. Sin embargo, si no es así, hay varias cuestiones:

  • Si usted está exponiendo la lista, sólo se debe siempre devolver una copia del mismo como un IEnumerable<PostVoteType> usando la palabra clave yield.
  • Asegúrese de que su PostVoteType es inmutable, de lo contrario las referencias se pueden cambiar y los campos utilizados podrían ser alterados
1

"Nunca" es una palabra muy difícil de hecho.

En su caso particular, afirma que no solo sus datos PostVoteType son absolutos e inmutables, sino que también lo es la colección de contenedores. Francamente, no creo que pueda saberlo, porque usted no es el negocio (su interpretación del requisito es imperfecta) y usted no es psíquico (su conocimiento del futuro es imperfecto).

Sugiero que almacene siempre los datos que no se pueden expresar como una enumeración en algún tipo del repositorio. Donde espera necesidades relacionales y/o transaccionales y/o mutables que signifiquen una base de datos, si espera una alta proporción de lectura a escritura que puede ser un archivo de configuración (que creo que este caso debería ser).

Editar: En términos de persistencia de memoria, estoy de acuerdo con otros en que la memoria caché es el mejor lugar para almacenar esto, o más bien en un objeto de dominio respaldado por caché.


Aparte: su construcción de PostVoteTypes es horrible - sugieren fuertemente desea una refactor :)

+0

oh yay, downvotes aleatorios nuevamente – annakata

+0

¿Qué hay de malo en ello? ¿Qué refactorización recomendarías? –

+5

Una de las peores no respuestas que he visto en SO. Usted hace suposiciones sobre los requisitos del negocio y luego castiga a la persona que formula la pregunta en función de sus propias suposiciones no fundamentadas y sesgos injustificados. Luego procedes a no dar ningún tipo de respuesta. Y no, mi voto no fue al azar. –

0

Cuando necesita acceder frecuentemente a los mismos datos, y no necesita almacenarlos en la base de datos subyacente, y que estos datos son aproximadamente los mismos en cada situación que la aplicación pueda encontrar, entonces sugiero usar el almacenamiento en caché. El almacenamiento en caché nace de estos requisitos.El almacenamiento en caché normalmente es la forma más rápida de proporcionar datos, ya que siempre se guardan en la memoria o algo similar para facilitar y facilitar el acceso de la aplicación.

Aquí hay una buena herramienta de caché provista con Microsoft Enterprise Library, Caching Application Block.

Creo que vale la pena tomarse el tiempo para aprender a usarlo de manera efectiva.

1

Al mirar su código, parece que está tratando de crear un conjunto de objetos que realmente coloque la enumeración PostVotePointValue en una especie de lista. Es decir. ya tienes lo que necesitas definido en solo la enumeración misma. Lo alentaría a no definir la misma información en dos lugares (este data store que está solicitando y la enumeración). Este es un error común que veo que hacen las personas. Crean una tabla/lista de búsqueda, luego crean una enumeración que refleja las filas de la tabla y eso significa que tienen que modificar dos lugares para cualquier cambio en la lista.

Si PostVotePointValue no es una enumeración, sino solo algunas constantes o si hay más información que está planeando incluir, entonces esto no es relevante.

He aquí algunos ejemplos de cómo trabajar con enumeraciones como 'listas' de 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)); 
     } 
    } 
} 

Usted debe ser capaz de adaptarse lo anterior en un enfoque que le dará una lista que se puede utilizar para el enlace de datos si lo necesita.

0

Me pregunto por qué no puedes usar una enumeración simple para esto?

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

Bueno, si el voto favorable vale 15 puntos, ¿cómo pondría el valor del punto en la enumeración? es posible? Por favor hagamelo saber. Gracias – Luke101

+0

siempre puede tener una lista estática y hacer algo como. var type = PostVoteType.UpVote; var points = new Dictionary (); valor var = puntos [tipo]; –

Cuestiones relacionadas