[英]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.