High Plains Grifter
High Plains Grifter

Reputation: 1571

C# Dictionary of Dictionaries returns null value from select when matched on key reference

The Console project code sample below is analogous to my code; irl there is a more complexity but the problem I am having is demonstrated adequately. I cannot understand why the linq select in the Demo method returns a null when one side seems of the where<> clause seems to match the expression used in the foreach loop to populate the other side of the where<> clause.

I have tried loads of different permutations of the same code, but whatever I do I am working with a null thisOrder; I can't seem to get past that to be able to work with anything.

What am I missing; why does my where clause not return the orders in the inner dictionary of the orders dictionary?

        using System;
        using System.Collections.Generic;
        using System.Linq;

namespace ShowTest
{
    public class Depot
    {
        public string Name { get; set; }
        public Dictionary<Order, Dictionary<int, OrderLine>> Orders { get; set; } = new Dictionary<Order, Dictionary<int, OrderLine>>(new OrderEqualityComparer());
    }
    public class Order
    {
        public string Reference { get; set; }
        public DateTime DepotDate { get; set; }
    }
    #region comparer
    public class OrderEqualityComparer : IEqualityComparer<Order>
    {
        public bool Equals(Order x, Order y)
        {
            return (x.Reference == y.Reference);
        }

        public int GetHashCode(Order obj)
        {
            return (obj.Reference.GetHashCode());
        }
    }
    #endregion
    public class OrderLine
    {
        public int Qty { get; set; }
        public string ExternalRef { get; set; }
    }
    public class Demo
    {
        public static void Main()
        {
            #region Setting up values
            Order order = new Order { DepotDate = DateTime.Parse("15/01/2010"), Reference = "myOrderRef" };
            OrderLine orderLine1 = new OrderLine { ExternalRef = "Foo", Qty = 4 };
            OrderLine orderLine2 = new OrderLine { ExternalRef = "Bar", Qty = 8 };

            var orderLines = new Dictionary<int, OrderLine>();
            orderLines.Add(1, orderLine1);
            orderLines.Add(2, orderLine2);

            var orders = new Dictionary<Order, Dictionary<int, OrderLine>>();
            orders.Add(order, orderLines);

            Depot myDepot = new Depot { Name = "Funhouse", Orders = orders };
            #endregion

            foreach (string oRef in myDepot.Orders.Select(l => l.Key.Reference))
            {
                //for each order reference, there is an order containing many order lines. So, first we get the relevant order
                var thisOrder = (from l in myDepot.Orders
                                 where l.Key.Reference == oRef
                                 select l.Value.Values) as Dictionary<int, OrderLine>;

                if (thisOrder == null) { Console.WriteLine("Why is thisOrder null when the search criterion was retrieved from the order itself?"); }
                else { Console.WriteLine("Hooray, the damnable thing has contents!"); }
            }
        }
    }
}

Upvotes: 0

Views: 740

Answers (1)

David
David

Reputation: 218827

Because you're interpreting thisOrder as the wrong type:

as Dictionary<int, OrderLine>

Since the result of the expression is not a Dictionary<int, OrderLine>, the result of trying to cast it to one is null. The result is a collection, and not even of Dictionary<int, OrderLine> objects but of Dictionary<int, OrderLine>.ValueCollection objects. (A collection which contains one element, but a collection nonetheless.)

You can select from that collection. For example, if what you want is a Dictionary<int, OrderLine>:

var thisOrder = (from l in myDepot.Orders
                 where l.Key.Reference == oRef
                 select l.Value).FirstOrDefault();

Overall the main point is that your querying works just fine, but you're telling the system to use the wrong types.

Upvotes: 2

Related Questions