2009-11-17 78 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