2009-11-17 80 views
0

假设我有一个像类以下内容:C# - 一个一流的设计问题 - 装载财产清单

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

现在的问题是,当我应该加载_machines列表?

我已经预料2种方式:

(1)在Stage.Get()方法:

像这样:

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

与此唯一的问题是,如果机器有一个List<T> - 属性(例如,List<Part> Parts等)和Machine.Get(stages[i].ID) - 方法具有类似的编码,这将以整个表的递归加载结束。就像这样,整个数据库可能已经加载到内存中。

(2)在属性直接访问数据库:

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

这样做的问题是:

(我)这将在一个巨大的性能损失结束:

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

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

因此,每次这种循环都投入使用时,必须访问数据库。

(ii)getset不得不在Save(),Update()等不同。

任何人都可以告诉我更好的方法吗?

回答

2

根据您的设计,每次访问属性时都不需要加载数据。相反,您可以检查是否已设置,只在需要时进行加载。这是一个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我有同样的事情写,刷新,并presto;你已经写了它。 – DancesWithBamboo 2009-11-17 05:36:53

+0

因此,只有一个空检查才能发挥重要作用。 – anonymous 2009-11-17 05:43:48