2011-08-26 8 views
5

La situación es que tengo una tabla que modela una entidad. Esta entidad tiene varias propiedades (cada una identificada por una columna en la tabla). La cuestión es que, en el futuro, necesitaría agregar nuevas propiedades o eliminar algunas. El problema es cómo modelar tanto la base de datos como el código correspondiente (usando C#) para que cuando aparezca esa ocasión sea muy fácil simplemente "tener" una nueva propiedad.Genéricos y base de datos: un problema de diseño

En el principio era sólo una propiedad, así que tenía una columna. Definí la propiedad correspondiente en la clase, con el tipo y el nombre apropiados, luego creé los procedimientos almacenados para leerla y actualizarla. Luego vino la segunda propiedad, copiado rápidamente, cambiado el nombre y tipo y un poco de SQL, y ahí estaba. Obviamente, este no es un modelo adecuado para el futuro. En este momento, algunos de ustedes pueden sugerir un ORM (EF u otro) porque esto generará el SQL y el código automáticamente, pero por ahora esta no es una opción para mí.

pensé en tener un solo procedimiento para la lectura de una propiedad (por nombre de la propiedad) y otra para actualizarlo (por nombre y valor) a continuación, algunos procedimientos generales para la lectura de un grupo o todas las propiedades de una entidad en la misma declaración . Esto puede sonar fácil en C# si considera usar genéricos, pero la base de datos no conoce los genéricos, por lo que no es posible tener una solución sólida.

Me gustaría tener una solución que es "tan fuertemente tipificado como sea posible", así que no necesito hacer un montón de fundición y de análisis. Definiría las propiedades disponibles en el código para que no adivine qué tiene disponible y use cadenas de magia y cosas por el estilo. Entonces, el proceso de agregar una nueva propiedad en el sistema solo significaría agregar una nueva columna a la tabla y agregar una nueva "definición" de propiedad en el código (por ejemplo, en una enumeración).

+0

¿Por qué no puedes usar el EF? Los genios de Microsoft ya se dieron cuenta y trabajaron mucho en este sentido. Odiaría verte volver a inventar la rueda. – Jay

+0

Sí, no entiendo por qué necesita evitar un ORM. (Además, no tengo idea de qué tienen que ver los genéricos C# con nada de esto) –

+0

Estoy de acuerdo, pero EF está un poco más adelante en lo que respecta a la arquitectura, así que no puedo usarla todavía. – CyberDude

Respuesta

2

Parece que usted quiere hacer esto:

MyObj x = new MyObj(); 
x.SomeProperty = 10; 

Tiene una tabla creada para eso, pero usted no desea mantener la alteración de la mesa cuando se agrega

x.AnotherProperty = "Some String"; 

Es necesario normalizar los datos de la tabla de este modo:

-> BaseTable 
    RecordId, Col1, Col2, Col3 

-> BaseTableProperty 
    PropertyId, Name 

-> BaseTableValue 
    ValueId, RecordId, PropertyId, Value 

Su clase se vería así:

public class MyObj 
{ 
     public int Id { get; set; } 
     public int SomeProperty { get; set; } 
     public string AnotherProperty { get; set; } 
} 

Cuando crea su objeto desde su DL, enumera el conjunto de registros. Luego, escriba el código una vez que inspeccione la propiedad con el mismo nombre que su configuración (BaseTableProperty.Name == MyObj.<PropertyName> - y luego intente el tipo de conversión a ese tipo mientras enumera el conjunto de registros.

Luego, simplemente agrega otra propiedad a su objeto, otro registro a la base de datos en BaseTableProperty, y luego se puede almacenar valores de ese tipo en BaseTableValue

Ejemplo:.

RecordId 
======== 
1 

PropertyId   Name 
==========   ==== 
1     SomeProperty 

ValueId  RecordId  PropertyId  Value 
=======  ========  ==========  ===== 
1   1    1    100 

usted tiene dos conjuntos de resultados, una para datos básicos, y una unieron de las tablas Propiedad y Valor.A medida que enumera cada registro, verá un Nombre de SomeProperty - ¿Existe typeof(MyObj).GetProperty("SomeProperty")? ¿Sí? ¿De qué se trata? ¿En t? Ok, a continuación, tratar de convertir "100" para int estableciendo la propiedad:

propertyInfo.SetValue(myNewObjInstance, Convert.ChangeType(dbValue, propertyInfo.PropertyType), null); 

Para cada propiedad.

+0

Acercamiento pero realmente no quiero ni necesito declarar cada propiedad de la clase. Raramente sucede que necesito más de una propiedad a la vez. La mayoría de las veces tengo el ID del objeto y necesito conocer solo una de las propiedades. Es por eso que iba a tener un método general 'GetProperty (int objectID, string propertyName)'. – CyberDude

+0

Aceptaré esto ya que es lo más cercano a la solución que voy a tomar. – CyberDude

0

Incluso si usted ha dicho que no se pueden utilizar, que es lo que más ORM hacer. Dependiendo de cuál use (o incluso cree si se trata de una experiencia de aprendizaje), variarán enormemente en complejidad y rendimiento. Si prefiere un ORM ligero, marque Dapper.Net. Hace uso de genéricos también, por lo que puede verificar el código, ver cómo funciona y crear su propia solución si es necesario.

Cuestiones relacionadas