繁体   English   中英

加载时无限循环 Object

[英]Infinite Loop When Loading Object

几天来,我一直在绞尽脑汁,试图在通过 class 中的方法将来自数据库的数据加载到我的类时不生成无限循环。

在一个有趣的例子中,这就是正在发生的事情。 考虑下面的 class:

    public class Person
{
    public int id { get; set; }
    public string name{ get; set; }
    public Person carrier{ get; set; }
}

在 class 内部的方法中,我将其定义为:

public void Load()
{
    Datatable tableResult;
    using (MySqlConnection con = new MySqlConnection(ConnectionString))
    {
        using (MySqlCommand com = new MySqlCommand(My.Resources.PersonSelect))
        {
            com.Parameters.AddWithValue("@ID", this.ID);
            using (MySqlDataAdapter adp = new MySqlDataAdapter(CmdPerson))
            {
                TableResult = new DataTable();
                adp.Fill(TableResult);
                if (tableResult.Rows.Count == 1)
                {
                    ID = tableResult.Rows(0).Item("id");
                    Name = tableResult.Rows(0).Item("name");
                    Carrier = new Person().Load(tableResult.Rows(0).Item("carrierid"));
                }
            }
        }
    }
}

还要考虑我有一个人,那个人的载体就是他自己。 这将产生一个无限循环。

我已经尝试在属性中实现 LazzyLoading,但我仍然不知道哪些类可能有同样的问题。 有没有其他方法可以解决这个问题?

你可以试试这个:

public void Load()
{
    using (MySqlConnection con = new MySqlConnection(ConnectionString))
    using (MySqlCommand com = new MySqlCommand(My.Resources.PersonSelect))
    using (MySqlDataAdapter adp = new MySqlDataAdapter(com))
    {
        com.Parameters.AddWithValue("@ID", this.ID);
        var TableResult = new DataTable();
        adp.Fill(TableResult);

        if (tableResult.Rows.Count == 1)
        {
            ID = tableResult.Rows(0).Item("id");
            Name = tableResult.Rows(0).Item("name");
            if (ID == tableResult.Rows(0).Item("carrierid"))
            {
                Carrier = this;
            }
            else 
            {
                Carrier = new Person().Load(tableResult.Rows(0).Item("carrierid"));
            }
        }
    }
}

它仍然有可能在链中出现循环(A 的承运人是人 B,他的承运人又是人 A),但如果您的数据中没有这种情况,您可能会没事。

否则,您可以选择延迟加载运营商,如下所示:

public class Person
{
    public int ID { get; set; }
    public string Name{ get; set; }

    private int _carrierID;
    private Person _carrier = null;
    public Person Carrier
    { 
       get 
       {
           if _carrier == null) _carrier = Person.Load(_carrierID);
           return _carrier;                  
       }
       private set
       {
            _carrier = value;  
            if (_carrier != null) _carrierID = _carrier.ID;
       }
    }

    public static Person Load(int ID)
    {
        using (MySqlConnection con = new MySqlConnection(ConnectionString))
        using (MySqlCommand com = new MySqlCommand(My.Resources.PersonSelect))
        using (MySqlDataAdapter adp = new MySqlDataAdapter(com))
        {
            com.Parameters.AddWithValue("@ID", ID);
            var TableResult = new DataTable();
            adp.Fill(TableResult);

            if (tableResult.Rows.Count == 1)
            {
                return new Person() {
                    ID = tableResult.Rows(0).Item("id"),
                    Name = tableResult.Rows(0).Item("name"),
                    _carrierid = tableResult.Rows(0).Item("carrierid")
                };
            }
            return null;
        }
    }
}

如果您尝试编写如下代码,这也可能永远循环:

var p = Person.Load(someID);
while (p.Carrier!=null)
{
   p = p.Carrier;
}

但至少现在你必须把循环放在可以找到它的地方。

另请注意我如何将Load()方法转换为static

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM