views:

108

answers:

1

Suppose I have a class like the following:

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()
    {  
    }
}

Now the question is, when should I load the _machines list?

I have anticipated 2 ways:

(1) In the Stage.Get() method:

Like this:

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;
}

The only problem with this is, if Machine has a List<T> - property (for example, List<Part> Parts, etc.), and the Machine.Get(stages[i].ID) - method has similar coding, this will end up in a recursive loading of entire table. And like this, the entire database may have been loaded in the memory.

(2) Direct Database Access in the property:

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; }
}

The problem with this is:

(i) This will end up in a huge performance loss:

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

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

Coz, everytime a loop of this kind is put into action, database must be accessed.

(ii) get and set have to be handeled differenly in Save(), Update() and so on.

Can anyone suggest me any better way?

+2  A: 

Given your design, you shouldn't need to load the data each time the property is accessed. Instead, you could check to see if it has been set yet and only do the load if needed. This is a lazy loading design.

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; }
}
Jeromy Irvine
+1 I had the same thing written, refreshed, and presto; you had already written it.
DancesWithBamboo
So, only a null check is making the difference.
JMSA