Question

Son probarbly un problème simple 3 niveaux. Je veux juste nous assurer que nous utilisons les meilleures pratiques pour cela et je ne suis pas familiary avec les structures encore.

Nous avons les 3 niveaux:

  • GUI: ASP.NET pour la présentation en couche (première plate-forme)
  • BAL: couche d'affaires sera en charge la logique sur un serveur web en C #, ainsi nous pouvons l'utiliser pour webforms / MVC + webservices
  • DAL: LINQ to SQL dans la couche de données, retour BusinessObjects non LINQ.
  • DB. Le SQL sera Microsoft SQL-server / Express (havent encore décidé)

Permet de penser à la configuration où nous avons une base de données [Personnes]. Ils peuvent tous avoir plusieurs adresses [] es et nous avons une liste complète de tous [PostalCode] et correspondant citynames etc.

L'accord est que nous avons rejoint un grand nombre de détails d'autres tables.

{Relations} / [tables]

  • [personne]: 1 --- N: {} PersonAddress: M --- 1: [Adresse]
  • [Adresse]: N --- 1: [PostalCode]

Maintenant, nous voulons construire la DAL pour personne. Comment le regard PersonBO et quand le joint occure? Est-ce un problème de la couche d'affaires pour aller chercher tous les citynames et addressses possibles pr. La personne? ou si le DAL terminer tout cela avant de retourner le PersonBO au BAL?

Class PersonBO 
{
    public int ID {get;set;}
    public string Name {get;set;}
    public List<AddressBO> {get;set;} // Question #1
} 

// Q1: pouvons-nous récupérer les objets avant de retourner le PersonBO et doit-il être un tableau à la place? ou est totalement faux pour ce n-tier / 3-tier ??

Class AddressBO 
{
    public int ID {get;set;}
    public string StreetName {get;set;}
    public int PostalCode {get;set;} // Question #2
} 

// Q2: pouvons-nous faire de la recherche ou tout simplement quitter la PostalCode pour la recherche plus tard

?

Quelqu'un peut-il expliquer dans quel ordre tirer les objets? La critique constructive est la bienvenue. : O)

Était-ce utile?

La solution

Vous êtes un peu réinventer la roue; ORM résoudre déjà la plupart de ce problème pour vous et vous allez le trouver un peu difficile à faire vous-même.

Les ORM façon comme LINQ to SQL, Entity Framework et NHibernate faire est une technique appelée chargement paresseux des associations (qui peut éventuellement être surchargée avec une charge avide).

Lorsque vous tirez une Person, il ne charge pas le Address jusqu'à ce que vous demandez spécifiquement pour elle, à quel point un aller-retour à la base de données se produit (charge paresseux). Vous pouvez également spécifier sur une base par requête que vous voulez que le Address à charger pour tous personne (charge impatient).

Dans un sens, cette question vous demande essentiellement que ce soit pour la AddressBO ou non effectuer des charges paresseux ou désireux de PersonBO, et la réponse est: non plus. Il n'y a pas une approche unique qui fonctionne universellement. Par défaut vous devez charger probablement paresseux, de sorte que vous ne faites pas beaucoup de jointures inutiles; afin de tirer ceci, vous devrez construire votre PersonBO avec un mécanisme de chargement paresseux qui maintient une référence à la DAL. Mais vous voulez toujours avoir la possibilité de hâte charge, que vous devez intégrer dans votre logique « affaires accès ».

Une autre option, si vous avez besoin de retourner des données hautement personnalisées définies avec des propriétés spécifiques peuplées de nombreuses tables différentes, est de ne pas retourner un PersonBO du tout, mais au lieu d'utiliser un Transfert de données objet (DTO). Si vous implémentez un mécanisme par défaut de chargement paresseux, vous pouvez parfois remplacer ce que la version avide de chargement.


FYI, chargeuses paresseux dans les cadres d'accès aux données sont généralement construits avec la logique de chargement dans l'association elle-même:

public class PersonBO
{
    public int ID { get; set; }
    public string Name { get; set; }
    public IList<AddressBO> Addresses { get; set; }
}

Ceci est juste un POCO, la magie se produit dans la mise en œuvre de la liste réelle:

// NOT A PRODUCTION-READY IMPLEMENTATION - DO NOT USE

internal class LazyLoadList<T> : IList<T>
{
    private IQueryable<T> query;
    private List<T> items;

    public LazyLoadList(IQueryable<T> query)
    {
        if (query == null)
            throw new ArgumentNullException("query");
        this.query = query;
    }

    private void Materialize()
    {
        if (items == null)
            items = query.ToList();
    }

    public void Add(T item)
    {
        Materialize();
        items.Add(item);
    }

    // Etc.
}

(Ceci est évidemment pas la production de qualité, il est juste de démontrer la technique;. Vous commencez avec une requête et ne pas se matérialiser la liste actuelle jusqu'à ce que vous devez)

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