Словарь словарей C # возвращает нулевое значение из выбора при совпадении по ключевой ссылке - PullRequest
0 голосов
/ 11 сентября 2018

Пример кода консольного проекта ниже аналогичен моему коду;У меня есть более сложная задача, но проблема, с которой я сталкиваюсь, продемонстрирована адекватно.Я не могу понять, почему linq select в методе Demo возвращает нулевое значение, когда одна сторона предложения where <> кажется совпадает с выражением, используемым в цикле foreach для заполнения другой стороны предложения where <>.

Я пробовал множество различных перестановок одного и того же кода, но что бы я ни делал, я работаю с нулем thisOrder;Я не могу пройти мимо этого, чтобы иметь возможность работать с чем-либо.

Чего мне не хватает;почему мое предложение where не возвращает заказы во внутреннем словаре словаря заказов?

        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!"); }
            }
        }
    }
}

1 Ответ

0 голосов
/ 11 сентября 2018

Поскольку вы интерпретируете thisOrder как неправильный тип:

as Dictionary<int, OrderLine>

Так как результат выражения не является Dictionary<int, OrderLine>, результат попытки привести его к одному равен null.В результате получается коллекция , и даже не Dictionary<int, OrderLine> объектов, а Dictionary<int, OrderLine>.ValueCollection объектов.(Коллекция, содержащая один элемент, но, тем не менее, коллекция.)

Вы можете выбрать из этой коллекции.Например, если вам нужен Dictionary<int, OrderLine>:

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

В целом, главное, что ваши запросы работают нормально, но вы говорите системе использовать неправильные типы.

...