Question

Le projet sur lequel je travaille utilise une architecture à plusieurs niveaux. Nos couches sont les suivantes:

  • Accès aux données
  • Logique d'entreprise
  • Entités commerciales
  • Présentation

La logique applicative appelle vers le bas dans la couche d'accès aux données, et la couche Présentation vers la couche logique d'entreprise et les entités métier sont référencées par toutes.

Nos entités commerciales correspondent essentiellement à notre modèle de données 1-1. Pour chaque table, nous avons une classe. Initialement, lors de la conception du cadre, la gestion des relations maître-détail ou enfant-parent n'était pas prise en compte. Par conséquent, toutes les entités de la logique commerciale, d'accès aux données et commerciales ne faisaient référence qu'à une seule table dans la base de données. Une fois que nous avons commencé à développer l’application, il est vite devenu évident que ne pas avoir ces relations dans notre modèle objet nous faisait très mal.

Toutes vos couches (y compris la base de données) sont toutes générées à partir d'une base de données de métadonnées interne, que nous utilisons pour gérer notre générateur de code développé localement.

La question est de savoir quel est le meilleur moyen de charger ou de charger paresseux les relations dans nos entités. Par exemple, supposons qu'une classe de personnes ait une relation maître-enfant avec une table d'adresses. Cela apparaît dans l'entité commerciale en tant que propriété de collection des adresses sur l'objet Personne. Si nous avons une relation un-à-un, cela apparaît comme une propriété d'entité unique. Quelle est la meilleure approche pour remplir et enregistrer les objets de relation? Nos entités commerciales n’ont aucune connaissance de la couche Business Logic, il est donc impossible de le faire en interne lorsque la propriété est appelée.

Je suis sûr qu'il existe une sorte de modèle standard pour le faire. Des suggestions?

En outre, il convient de noter que la couche DataAcess utilise la réflexion pour créer nos entités. Les procédures stockées renvoient un résultat sélectionné à partir d'une table et en utilisant la réflexion, nous peuplons notre objet métier en faisant correspondre les noms des propriétés aux noms des colonnes. Faire des jointures serait donc difficile.

Était-ce utile?

La solution

Je recommande vivement de consulter le livre de Patterns of Enterprise Architecture de Fowler. Il propose différentes approches pour résoudre ce type de problème, qu'il décrit bien, y compris les relations entre entités.

L’un des éléments les plus intéressants est le modèle d’Unité de travail, qui est essentiellement un collecteur, qui observe les actions effectuées sur vos entités. Une fois que vous avez terminé, il regroupe les appels de base de données appropriés et effectue la demande à la base de données. Ce modèle est l’un des concepts centraux utilisés par NHibernate , qui utilise un objet implémentant IDisposable pour signaler la fin du "travail". Cela vous permet d'envelopper vos actions dans une utilisation et de laisser l'unité de travail les gérer pour vous.

Modifier: informations complémentaires

Ceci est un lien vers la structure de classe de base de l'Unité de travail ... pas vraiment la chose la plus excitante au monde. Fowler fournit plus de détails dans son livre, dont vous pouvez voir certains ici . Vous pouvez également considérer l’objet Session de NHibernate comme une implémentation possible (j’ai été en mesure de localiser le Interface ISession : vous ne savez pas où réside l'implémentation)

J'espère que cela vous aidera.

Autres conseils

Une approche que j'ai utilisée par le passé consiste à rendre le type de conteneur suffisamment intelligent pour récupérer les objets requis. par exemple:

public class Relation<T>
{
  private T _value;

  private void FetchData()
  {
    if( LoadData != null ) {
      LoadDataEventArgs args = new LoadDataEventArgs(typeof(T), /* magic to get correct object */);
      LoadData(this, args);
      _value = (T)args.Value;
    }
  }

  public event EventHandler<LoadDataEventArgs> LoadData;

  public T Value {
    get {
      if( _value == default(T) )
        FetchData();
      return _value; 
    }
    set { /* Do magic here. */ }
  }
}

Ensuite, vous le déclarez sur votre entité comme suit:

[RelationCriteria("ID", EqualsMyProperty="AddressID")]
public Relation<Address> Address {
  get; set;
}

Et c'est au chargeur du type qui déclare la propriété Address d'ajouter un gestionnaire à l'événement LoadData.

Une classe similaire implémente IList pour vous donner une relation un à plusieurs.

Quelle langue utilisez-vous? Ce que vous avez décrit correspond exactement à ce que fait Entity Framework dans .Net. Mais vous n'avez pas indiqué la langue que vous utilisiez et je suppose que vous ne voulez réécrire aucun de vos données.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top