2009-04-22 13 views
6

Estoy trabajando en un pequeño proyecto educativo para ejercer perst.net.Muchos a muchos se oponen a la relación de objeto en C#

Tenemos un pequeño problema de diseño, que es cómo resolver mejor la relación entre dos clases de objetos, es decir, el participante y campeonato. Es una relación de muchos a muchos como participante puede participar en muchos campeonatos y campeonatos puede tener un múltiplo participantes.

Por favor, recomiende cómo hacer esto mejor en C#, ¿debería usar la clase técnica 'DB relacional'?

Respuesta

1

No estoy seguro de si esto funciona para su diseño o requisitos, pero que podría ser posible ...

Obviamente una relación de muchos a muchos es más fácil de representar con un tercer objeto que gestiona la relación . En su caso, sería un participante en el campeonato. En lugar de tener una colección en su clase participante que tenga campeonatos y viceversa, pídales que tengan una instancia para esta tercera clase. El objeto championshipparticipant gestiona esta relación. Luego se puede serializar a la base de datos directamente como una tabla de unión.

4

Puede tener cualquier relación en la que un elemento en particular pueda tener varios elementos asociados utilizando propiedades de IEnumerable (u otras colecciones). En el ejemplo, esto se vería de la siguiente manera:

class Participant { 
    public IEnumerable<Championship> Championships { 
     get { 
     return _championships; 
     } 
    } 
    private List<Championship> _championships; 
} 

Algunas cosas importantes a tener en cuenta:

  • lo que éste debería una propiedad de sólo lectura. Esto a veces es confuso para las personas, especialmente si tiene algo modificable como un ICollection devuelto en lugar de un IEnumerable. Hacer que la propiedad sea de solo lectura no impide la modificación de la colección , sino la modificación de la lista completa .

  • Estrategias de carga: Notará en el ejemplo anterior que la colección no está activada. Normalmente hace esto en el constructor o cuando se accede por primera vez a la propiedad (llamada creación de instancias vagas): en general, la instanciación lenta agrega cierta complejidad pero puede aumentar el rendimiento, especialmente si esta colección no se usa a menudo o si tiene muchos de estos tipos de propiedades.

  • Generalmente, es una buena idea elegir una clase para "mantener" la otra clase en el caso de muchos a muchos (es decir, los participantes tienen propiedades de campeonato pero los campeonatos no tienen propiedades de participantes o viceversa). Esto reduce la cantidad de código que tiene que escribir y reduce la complejidad y su área de superficie con su base de datos. Si se necesita una llamada para la otra dirección, considere una llamada al método en lugar de una propiedad. Recuerde que muchos a muchos desde un sentido relacional no necesariamente significa que es el caso de uso común (como usuario, solo quiero agregar participantes a campeonatos en lugar de campeonatos a los participantes)

  • Si su colección es modificable, recuerde que enviar un Guardar implica que las colecciones debajo de él también deberían modificarse si se cambiaran.Esto puede agregar una gran cantidad de complejidad (En el pasado, he utilizado las listas internas para almacenar elementos añadidos/eliminados)

+0

Wow. Gran awser. –

8

Si usted está buscando un objeto orientado (o dominio Driven Design) enfoque a continuación un tercer objeto para manejar la 'unión' es completamente la manera incorrecta de hacer esto. Puede utilizar ILists/enumerables con ADD ... métodos para manejar esto de la siguiente manera:

public class Participant 
{ 
    private readonly IList<Championship> _championships = new List<Championship>(); 

    public IEnumerable<Championship> Championships 
    { 
     get { return _championships; } 
    } 

    internal void AddChampionship(Championship championship) 
    { 
     if (!_championships.Contains(championship)) 
      _championships.Add(championship); 
    } 
} 

public class Championship 
{ 
    private readonly IList<Participant> _participants = new List<Participant>(); 

    public IEnumerable<Participant> Participants 
    { 
     get { return _participants; } 
    } 

    public void AddParticipant(Participant participant) 
    { 
     if (_participants.Contains(participant)) return; 
     _participants.Add(participant); 
     participant.AddChampionship(this); 
    } 
} 

La clave aquí es asegurarse de que usted maneja la relación de un solo lado - por ejemplo, en este caso, sería llamando al campeonato.AddParticipant()

+1

¡Gran respuesta! La última declaración es crucial ... ¡debes hacer que sea audaz! +1 – Cerebrus

Cuestiones relacionadas