Question

I have a function that returns a Hashtable. The var dt gets a bunch of RevenueGroupIDs and ProductIDs from the database that map together in a 1-to-many structure. For example:

RevenueGroupID ProductID
1                 312
1                 313
1                 315
2                 317
2                 319
3                 401
3                 410
3                 411
3                 415

The combination of these 2 numbers are always unique -- no repeats. The function builds a Hashtable dictionary of key-value pairs in which the key is always a RevenueGroupID and the value is a List<int> of all the ProductIDs for that RevenueGroupID. The problem is: each time a key-value pair is added, all previous key-value pairs get overwritten with the current one. So at the end, ALL key value pairs are identical to the final one. I have stepped through the code and verified that each key-value pair is correct and unique. I can't see any reason for the reset. I have looked suspiciously at "productIDs.Clear();", but I can't see why that would be messing up the hashtable.

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;
}
Était-ce utile?

La solution

This is because you keep adding productIDs list to a hash table without making a copy, and then clear the content:

ht.Add(lastRevenueGroupID, productIDs);
productIDs.Clear(); // This removes all entries from the item stored at the lastRevenueGroupID key

This means that the same object is added over and over again, so you end up with multiple copies of the list that has the content of the last entry.

An easy fix is to make a new list before adding it to hash table, like this:

ht.Add(lastRevenueGroupID, productIDs.ToList());
productIDs.Clear();

Autres conseils

The problem is that you are only using one list instead of creating a new list for each item. Adding the list to the hash table doesn't create a copy of the list, it just adds the reference. When you clear the list you will clear the list for all previously added items in the hash table, because they are all the same list.

You can create a new list and add to the hash table when you start a new group. As you keep the reference to the list, you can keep adding numbers to it after it is places in the hash table:

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

Note: Consider using the strictly typed Dictionary<int, List<int>> instead of Hashtable.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top