Pregunta

[ACTUALIZACIÓN] El enfoque elegido se encuentra a continuación, como respuesta a esta pregunta.

Hola,

He estado buscando sobre este tema pero realmente no puedo encontrar lo que estoy buscando...

Con tablas de códigos me refiero a:cosas como 'estado civil', género, estados legales o sociales específicos...Más específicamente, estos tipos solo tienen propiedades establecidas y los elementos no van a cambiar pronto (pero podrían).Las propiedades son un Id, un nombre y una descripción.

Me pregunto cómo manejarlos mejor en las siguientes tecnologías:

  • en la base de datos (¿varias tablas, una tabla con diferentes claves de código...?)

  • creando las clases (probablemente algo así como heredar ICode con ICode.Name e ICode.Description)

  • creando la vista/presentador para esto:Debería haber una pantalla que los contenga todos, es decir, una lista de los tipos (género, estado civil...) y luego una lista de valores para ese tipo con un nombre y descripción para cada elemento en la lista de valores.

Estas son cosas que aparecen en cada proyecto, por lo que debe haber algunas mejores prácticas sobre cómo manejarlas...

Para que conste, no me gusta mucho usar enumeraciones para estas situaciones...Cualquier argumento sobre su uso aquí también es bienvenido.

[HACER UN SEGUIMIENTO]

Ok, recibí una buena respuesta de CodeToGlory y Ahsteele.Refinemos esta pregunta.

Digamos que no estamos hablando de género o estado civil, cuyos valores definitivamente no cambiarán, sino de "cosas" que tienen un Nombre y una Descripción, pero nada más.Por ejemplo:Estatus sociales, Estatutos jurídicos.

Interfaz de usuario:Solo quiero una pantalla para esto.Cuadro de lista con posibles tipos de nombre y descripción (los llamaré así), cuadro de lista con posibles valores para el tipo de nombre y descripción seleccionado y luego un campo de nombre y descripción para el elemento de tipo nombre y descripción seleccionado.

¿Cómo podría manejarse esto en Ver y Presentadores?Encuentro la dificultad aquí de que los tipos NameAndDescription deberían extraerse del nombre de la clase.

DB:¿Cuáles son las ventajas y desventajas de las tablas de búsqueda múltiples o individuales?

¿Fue útil?

Solución 3

He decidido ir con este enfoque:

CodeKeyManager mgr = new CodeKeyManager();
CodeKey maritalStatuses = mgr.ReadByCodeName(Code.MaritalStatus);

Donde:

  • CodeKeyManager puede recuperar CodeKeys de DB (Clave de código = MaritalStatus)
  • El código es una clase llena de constantes, volviendo cuerdas para Code.MaritalStatus = "maritalStatus". Estas constantes se asignan a la mesa de Clave de código> CodeKeyName
  • En la base de datos, tengo 2 tablas:
    • Clave de código con Id, CodeKeyName
    • CodeValue con CodeKeyId, ValueName, ValueDescription

DB:

texto alternativo http://lh3.ggpht.com/_cNmigBr3EkA /SeZnmHcgHZI/AAAAAAAAAFU/2OTzmtMNqFw/codetables_1.JPG

Código de clase:

public class Code
{
    public const string Gender = "gender";
    public const string MaritalStatus = "maritalStatus";
}

Clave de código Clase:

public class CodeKey
{
    public Guid Id { get; set; }
    public string CodeName { get; set; }

    public IList<CodeValue> CodeValues { get; set; }
}

Clase CodeValue:

public class CodeValue
{
    public Guid Id { get; set; }

    public CodeKey Code { get; set; }

    public string Name { get; set; }
    public string Description { get; set; }

}

Me parece de lejos la forma más fácil y más eficiente:

  • todo el código-datos se pueden visualizar de una manera idéntica (en la misma vista / presentador)
  • No necesito para crear tablas y clases para cada tabla de códigos que está por venir
  • Pero todavía puedo sacarlos de la base de datos fácilmente y usarlos fácilmente con la Clave de código constantes ...
  • NHibernate puede manejar esto fácilmente también

La única cosa que todavía estoy considerando es tirar hacia fuera del Id GUID y el uso de códigos de cadena (nchar) para su uso en la lógica de negocio.

Gracias por las respuestas! Si hay cualquier comentario sobre este enfoque, por favor!

Otros consejos

El uso de tablas de códigos con bases de datos puede muy útil. Puede hacer cosas como definir la vida de los datos (utilizando fechas de inicio y fin), agregar datos a la tabla en tiempo real por lo que no tiene que implementar el código, y puede permitir a los usuarios (con los privilegios adecuados, por supuesto) añadir datos a través de las pantallas de administración.

Yo recomendaría siempre utilizando una clave autonumber primaria en lugar del código o la descripción. Esto permite utilizar varios códigos (del mismo nombre pero con diferentes descripciones) durante diferentes períodos de tiempo. Además la mayoría de los administradores de bases (en mi experiencia) y no utilizan el autonumber sobre claves primarias basadas en texto.

Me gustaría utilizar una sola tabla por la lista codificada. Se puede poner múltiples códigos de todos en una mesa que no se relacionan (usando una matriz de clases), pero que se complica y sólo he encontrado un par de situaciones en las que era incluso útil.

Un par de cosas aquí:

  1. Use enumeraciones que son explícitamente clara y no va a cambiar. Por ejemplo, MaritalStatus, género, etc.

  2. mesas Uso de búsqueda para artículos que no son fijos como antes y se puede cambiar, aumentar / disminuir con el tiempo.

Es muy típico tener tablas de búsqueda en la base de datos. Definir un / objeto de valor clave en su capa de negocio que puede trabajar con la vista / presentación.

Me apoyo hacia el uso de una representación de la tabla para este tipo de datos. En última instancia, si usted tiene una necesidad de capturar los datos que va a tener una necesidad de almacenarlo. A efectos de notificación que es mejor tener un lugar que puede llamar la que los datos de a través de una llave. Para los propósitos de normalización encuentro tablas de búsqueda de propósito único sea más fácil que una de usos múltiples tablas de búsqueda.

Dicho esto enumeraciones funcionan bastante bien para las cosas que no cambiarán como el género, etc.

¿Por qué todos quieren complicar las tablas de códigos? Sí, hay un montón de ellos, pero son simples, por lo que los mantienen de esa manera. Sólo tratarlos como nunca otro objeto. Tu forman parte del dominio, por lo modelar como parte del dominio, nada especial. Si no cuando inevitibly necesita más atributos o funciones, tendrá que deshacer todo el código que actualmente lo utiliza y rehacerlo.

una tabla por supuesto (de integridad referencial y de modo que están disponibles para la presentación de informes).

Para las clases, de nuevo uno por supuesto, porque si escribo un método para recibir un objeto "Género", yo no quiero ser capaz de pasar accidentalmente una "MarritalStatus"! Deje la ayuda de compilación a eliminar a error de ejecución, es por eso que está allí. Cada clase puede heredar o simplemente contener una tabla de códigos de clase o lo que sea, pero eso es simplemente un ayudante de aplicación.

En la interfaz de usuario, si lo hace, de hecho, utilizar la tabla de códigos heredados, supongo que se podría utilizar eso para ayudar a salir y simplemente mantenerla en una interfaz de usuario.

Como regla general, no ensucia el modelo de base de datos, no ensucie el modelo de negocio, pero que Wnt para atornillar todo un poco en el modelo de interfaz de usuario, que no es tan malo.

Me gustaría considerar la simplificación de este enfoque aún más. En lugar de 3 mesas que definen los códigos (Code, Clave de código y CodeValue) sobre cómo sólo una tabla que contiene tanto los tipos de códigos y los valores de código? Después de todo los tipos de código son sólo otra lista de códigos.

Tal vez una definición de la tabla siguiente:

CREATE TABLE [dbo].[Code](
    [CodeType] [int] NOT NULL,
    [Code] [int] NOT NULL,
    [CodeDescription] [nvarchar](40) NOT NULL,
    [CodeAbreviation] [nvarchar](10) NULL,
    [DateEffective] [datetime] NULL,
    [DateExpired] [datetime] NULL,
CONSTRAINT [PK_Code] PRIMARY KEY CLUSTERED 
(
    [CodeType] ASC,
    [Code] ASC
)
GO

Puede haber un registro raíz con CodeType = 0, Código = 0, lo que representa el tipo de CodeType. Todos los registros CodeType tendrá un CodeType = 0 y un Código> = 1. He aquí algunos datos de ejemplo que podría ayudar a aclarar las cosas:

SELECT CodeType, Code, Description FROM Code

Results:

CodeType    Code    Description
--------    ----    -----------
0           0       Type
0           1       Gender
0           2       Hair Color
1           1       Male
1           2       Female
2           1       Blonde
2           2       Brunette
2           3       Redhead

Una restricción de comprobación podría añadirse a la Tabla de cifrado para asegurar que un CodeType válida se introduce en la tabla:

ALTER TABLE [dbo].[Code] WITH CHECK ADD CONSTRAINT [CK_Code_CodeType]   
CHECK (([dbo].[IsValidCodeType]([CodeType])=(1)))
GO

El IsValidCodeType función podría definirse así:

CREATE FUNCTION [dbo].[IsValidCodeType]
(
    @Code INT
)
RETURNS BIT
AS
BEGIN
    DECLARE @Result BIT
    IF EXISTS(SELECT * FROM dbo.Code WHERE CodeType = 0 AND Code = @Code)
        SET @Result = 1
    ELSE
        SET @Result = 0
    RETURN @Result
END
GO

Una cuestión que se ha planteado es cómo asegurar que una tabla con una columna de código tiene un valor adecuado para ese tipo de código. Esto también podría ser aplicada por una restricción de comprobación mediante una función.

Aquí hay una tabla persona que tiene una columna de género. Podría ser una buena práctica para nombrar todas las columnas de código con la descripción del tipo de código (Sexo en este ejemplo), seguido de la palabra de código:

CREATE TABLE [dbo].[Person](   
    [PersonID] [int] IDENTITY(1,1) NOT NULL,
    [LastName] [nvarchar](40) NULL,
    [FirstName] [nvarchar](40) NULL,
    [GenderCode] [int] NULL,
CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED ([PersonID] ASC)
GO

ALTER TABLE [dbo].[Person] WITH CHECK ADD CONSTRAINT [CK_Person_GenderCode] 
CHECK (([dbo].[IsValidCode]('Gender',[Gendercode])=(1)))
GO

IsValidCode se podría definir de esta manera:

CREATE FUNCTION [dbo].[IsValidCode]
(
    @CodeTypeDescription NVARCHAR(40),
    @Code INT
)
RETURNS BIT
AS
BEGIN
    DECLARE @CodeType INT
    DECLARE @Result BIT

    SELECT @CodeType = Code
    FROM dbo.Code
    WHERE CodeType = 0 AND CodeDescription = @CodeTypeDescription

    IF (@CodeType IS NULL)
    BEGIN
        SET @Result = 0
    END
    ELSE
    BEGiN
    IF EXISTS(SELECT * FROM dbo.Code WHERE CodeType = @CodeType AND Code = @Code)
        SET @Result = 1
    ELSE
        SET @Result = 0
    END

    RETURN @Result
END
GO

Otra función podría ser creado para proporcionar la descripción del código cuando se consulta una tabla que tiene una columna de código. Aquí se presenta una ejemplo de consultar la tabla Persona:

SELECT PersonID,
    LastName,
    FirstName,
    GetCodeDescription('Gender',GenderCode) AS Gender
FROM Person

Todo esto fue concebido desde la perspectiva de la prevención de la proliferación de las tablas de búsqueda en la base de datos y proporcionar una tabla de búsqueda. No tengo ni idea de si este diseño podría funcionar bien en la práctica.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top