C# - 类设计问题 - 加载属性列表

时间:2009-11-17 05:19:45

标签: c# class-design

假设我有类似以下的类:

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列表?

我预料到了两种方式:

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

唯一的问题是,如果Machine具有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; }
}

问题在于:

(i)这将导致巨大的性能损失:

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

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

Coz,每当这种循环投入使用时,必须访问数据库。

(ii)getset必须在Save()Update()等不同情况下进行不同的处理。

有人能建议我更好的方法吗?

1 个答案:

答案 0 :(得分: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; }
}