C#哈希表值会随着每个新键重置
我有一个返回哈希表的函数。var dt从数据库中获取一组RevenueGroupId和ProductId,它们以1对多的结构映射在一起。例如:C#哈希表值会随着每个新键重置,c#,collections,hashtable,C#,Collections,Hashtable,我有一个返回哈希表的函数。var dt从数据库中获取一组RevenueGroupId和ProductId,它们以1对多的结构映射在一起。例如: RevenueGroupID ProductID 1 312 1 313 1 315 2 317 2 319 3 401 3 410
RevenueGroupID ProductID
1 312
1 313
1 315
2 317
2 319
3 401
3 410
3 411
3 415
这两个数字的组合总是唯一的——没有重复。该函数构建一个键值对哈希表字典,其中键始终是RevenueGroupID,值是该RevenueGroupID的所有ProductId的列表。问题是:每次添加键值对时,所有以前的键值对都会被当前键值对覆盖。因此,在最后,所有键值对都与最后一个相同。我已经仔细检查了代码,并验证了每个键值对都是正确的和唯一的。我看不出重置的任何原因。我怀疑地查看了“productIDs.Clear();”,但我不明白为什么这会弄乱哈希表
public static Hashtable GetAllProductIDsInAllRevenueGroups()
{
var productIDs = new List<int>();
var ht = new Hashtable();
string sql = @" {my sql here}";
var dt = Utilities.GetDataTableForQuery(sql, null);
int counter = 0;
int revenueGroupID = 0;
int lastRevenueGroupID = 0;
foreach (DataRow row in dt.Rows)
{
revenueGroupID = Utilities.SafeInt(row["RevenueGroupID"]);
int productID = Utilities.SafeInt(row["ProductID"]);
if (revenueGroupID != lastRevenueGroupID && counter > 0)
{
ht.Add(lastRevenueGroupID, productIDs);
productIDs.Clear();
}
productIDs.Add(productID);
lastRevenueGroupID = revenueGroupID;
counter++;
}
ht.Add(lastRevenueGroupID, productIDs);
return ht;
}
public静态哈希表GetAllProductIDsInAllRevenueGroups()
{
var productIDs=新列表();
var ht=新哈希表();
字符串sql=@“{mySQL here}”;
var dt=Utilities.GetDataTableForQuery(sql,null);
int计数器=0;
int revenueGroupID=0;
int lastRevenueGroupID=0;
foreach(数据行中的数据行)
{
revenueGroupID=Utilities.SafeInt(第[“revenueGroupID”]);
int productID=Utilities.SafeInt(第[“productID”]行);
如果(revenueGroupID!=lastRevenueGroupID&&counter>0)
{
ht.Add(lastRevenueGroupID、productid);
productIDs.Clear();
}
productID.Add(productID);
lastRevenueGroupID=revenueGroupID;
计数器++;
}
ht.Add(lastRevenueGroupID、productid);
返回ht;
}
这是因为您一直在向哈希表中添加productId
列表,而不进行复制,然后清除内容:
ht.Add(lastRevenueGroupID, productIDs);
productIDs.Clear(); // This removes all entries from the item stored at the lastRevenueGroupID key
这意味着同一个对象被一次又一次地添加,因此最终会得到包含最后一个条目内容的列表的多个副本
一个简单的解决方法是在将列表添加到哈希表之前创建一个新列表,如下所示:
ht.Add(lastRevenueGroupID, productIDs.ToList());
productIDs.Clear();
问题是您只使用一个列表,而不是为每个项目创建新列表。将列表添加到哈希表不会创建列表的副本,它只是添加引用。清除列表时,将清除哈希表中以前添加的所有项的列表,因为它们都是相同的列表 您可以创建一个新列表,并在启动新组时添加到哈希表中。在保留对列表的引用时,可以在列表被放入哈希表后继续向列表中添加数字:
public static Hashtable GetAllProductIDsInAllRevenueGroups()
{
var productIDs;
var ht = new Hashtable();
string sql = @" {my sql here}";
var dt = Utilities.GetDataTableForQuery(sql, null);
int counter = 0;
int revenueGroupID = 0;
int lastRevenueGroupID = 0;
foreach (DataRow row in dt.Rows)
{
revenueGroupID = Utilities.SafeInt(row["RevenueGroupID"]);
int productID = Utilities.SafeInt(row["ProductID"]);
if (counter == 0 || revenueGroupID != lastRevenueGroupID)
{
productIDs = new List<int>();
ht.Add(revenueGroupID, productIDs);
}
productIDs.Add(productID);
lastRevenueGroupID = revenueGroupID;
counter++;
}
return ht;
}
public静态哈希表GetAllProductIDsInAllRevenueGroups()
{
var-productIDs;
var ht=新哈希表();
字符串sql=@“{mySQL here}”;
var dt=Utilities.GetDataTableForQuery(sql,null);
int计数器=0;
int revenueGroupID=0;
int lastRevenueGroupID=0;
foreach(数据行中的数据行)
{
revenueGroupID=Utilities.SafeInt(第[“revenueGroupID”]);
int productID=Utilities.SafeInt(第[“productID”]行);
如果(计数器==0 | | revenueGroupID!=lastRevenueGroupID)
{
productId=新列表();
ht.Add(revenueGroupID、ProductId);
}
productID.Add(productID);
lastRevenueGroupID=revenueGroupID;
计数器++;
}
返回ht;
}
注意:考虑使用严格类型的<代码>字典<代码>,而不是<代码>哈希表 .< /P> DasBrink:您的解决方案看起来很有前途,但没有编译。“'System.Collections.Generic.List'不包含'ToList'的定义”非常有用。谢谢,达斯!Guffa:我不知道该怎么做,因为在将ProductID添加到哈希表之前,您正在初始化它。它总是空的。@SweatCoder:当您将列表添加到哈希表中时,列表将为空,但随后您将数字添加到列表中。哈希表不包含列表的副本,它包含对列表的引用,因此它将与
productIDs
变量引用的列表相同。