Tengo una aplicación que tiene un concepto de Venue
, un lugar donde ocurren los eventos. A Venue
tiene muchos VenuePart
s. Por lo tanto, se ve así:¿Cómo organizo clases de C# que heredan unas de otras, pero también tienen propiedades que heredan unas de otras?
public abstract class Venue
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<VenuePart> VenueParts { get; set; }
}
Un Venue
puede ser un GolfCourseVenue
, que es un Venue
que tiene una pendiente y un tipo específico de VenuePart
llama HoleVenuePart
:
public class GolfCourseVenue : Venue
{
public string Slope { get; set; }
public virtual ICollection<HoleVenuePart> Holes { get; set; }
}
En el futuro, también puede haber otros tipos de Venue
s que hereden de Venue
. Pueden agregar sus propios campos y siempre tendrán VenuePart
de su propio tipo específico.
Éstos son los VenuePart
clases:
public abstract class VenuePart
{
public int Id { get; set; }
public string Name { get; set; }
public abstract string NameDescriptor { get; }
}
public class HoleVenuePart : VenuePart
{
public override string NameDescriptor { get { return "Hole"; } }
public int Yardage { get; set; }
}
Mis declaraciones anteriores parecen mal, porque ahora tengo una GolfCourseVenue
con dos colecciones, cuando en realidad sólo debe tener el uno. No puedo anularlo, porque el tipo es diferente, ¿verdad? Cuando ejecuto informes, me gustaría referirme genéricamente a las clases, donde escupo Venue
sy VenuePart
s. Pero, cuando presento formularios y tal, me gustaría ser específico.
Tengo muchas relaciones como esta y me pregunto qué estoy haciendo mal. Por ejemplo, tengo un Order
que tiene OrderItem
s, pero también tipos específicos de Order
s que tienen tipos específicos de OrderItem
s.
Actualización: Debo notar que estas clases son entidades Entity Framework Code-First. Esperaba que esto no importara, pero creo que sí. Necesito estructurar las clases de forma que Code-First pueda crear tablas de forma adecuada. No parece que Code-First pueda manejar genéricos. Lo sentimos, este detalle de implementación se está en el camino de una solución elegante:/
Actualización 2: Alguien vinculado a una búsqueda que apuntó a Covariance and Contravariance, lo que parecía ser una manera de limitar las listas dentro de los subtipos que ser de una determinada subtipo ellos mismos. Eso parece muy prometedor, ¡pero la persona borró su respuesta! ¿Alguien tiene información sobre cómo puedo aprovechar estos conceptos?
Actualización 3: Se han eliminado las propiedades de navegación que se encontraban en los objetos secundarios, porque confundía a las personas y no ayudaba a describir el problema.
Agregué las clases Part para que pudieras ver por qué tenía que haber 'abstract'. Pero, tienes razón sobre Venue. Eso no necesita ser abstracto. – Chris
¿Puedo usar [covarianza] (http://msdn.microsoft.com/en-us/library/dd799517.aspx) en el constructor de GolfCourseVenue para restringir su colección VenuePart a HoleVenueParts? ¿Estás familiarizado con los altibajos de esto? No creo que pueda utilizar su solución genérica porque EF no maneja esto. – Chris