2009-11-17 2 views
0

Supposons que j'ai une classe comme les suivantes:C# - Un problème de classe Design - propriété Loading Liste

public class Stage 
{ 
    public int ID {get; set;} 
    public strint Code {get; set;} 
    public string Name {get; set;} 

    private List<Machine> _machines; 
    public List<Machine> Machines 
    { 
     get{ return _machines; } 
     set{ _machines = value; } 
    } 

    ......... 
    ......... 

    // This method returns all the Stages stored 
    // in the Stage-table in the database. 
    public static List<Stage> Get() 
    {  
    } 
} 

Maintenant, la question est, quand dois-je charger la liste _machines?

J'ai prévu 2 façons:

(1) Dans la méthode Stage.Get():

Comme ceci:

public static List<Stage> Get() 
{ 
    List<Stage> stages = null; 

    try 
    { 
     //Begin transaction... 


     //Retrieve all Stages and put them in List<Stage> stages 
     ................. 
     ................. 

     //End transaction... 

     if(stages!=null) 
     { 
      //Now load Machines for each Stage 
      for(int i=0 ; i<stages.Count ; i++) 
      { 
       //Get Machines by Stage ID and put them on List<Machine> 
       stages[i].Machines = Machine.Get(stages[i].ID); 
      } 
     }  
    } 
    catch(Exception ex) 
    { 
     stages = null; 

     throw ex; 
    } 

    return stages; 
} 

Le seul problème avec ceci est, si la machine a une List<T> - propriété (par exemple, List<Part> Parts, etc.), et la méthode Machine.Get(stages[i].ID) a un codage similaire, cela se terminera par un chargement récursif de la table entière. Et comme ça, la base de données entière peut avoir été chargée dans la mémoire.

(2) Base de données Access directe dans la propriété:

private List<Machine> _machines; 
public List<Machine> Machines 
{ 
    get 
    { 
     //Get Machines by Stage ID and put them on List<Machine> 
     _machines = Machine.Get(this.ID); 

     return _machines; 
    } 
    set{ _machines = value; } 
} 

Le problème est:

(i) Cela finira dans une énorme perte de performance:

Stage stage = Stage.Get(...ID...); 

foreach(Machine m in stage.Machine) 
{ 
    //Do something 
    .............. 
} 

Coz, chaque fois qu'une boucle de ce type est mise en action, la base de données doit être accessible.

(ii) get et set doivent être handeled differenly dans Save(), Update() et ainsi de suite.

Quelqu'un peut-il me suggérer un meilleur moyen? Compte tenu de votre conception, vous ne devriez pas avoir besoin de charger les données chaque fois que la propriété est accédée.

Répondre

2

Au lieu de cela, vous pouvez vérifier si elle a déjà été définie et ne faire que la charge si nécessaire. C'est un design lazy loading.

private List<Machine> _machines; 
public List<Machine> Machines 
{ 
    get 
    { 
     //Get Machines by Stage ID and put them on List<Machine> 
     //only if we have not already done so 
     if (_machines == null) 
     { 
      _machines = Machine.Get(this.ID); 
     } 

     return _machines; 
    } 
    set{ _machines = value; } 
} 
+0

+1 J'avais la même chose écrite, rafraîchie, et presto; tu l'avais déjà écrit. – DancesWithBamboo

+0

Ainsi, seule une vérification nulle fait la différence. – anonymous

Questions connexes