【问题标题】:C# Dictionary of Dictionaries returns null value from select when matched on key referenceC# 字典字典在键引用上匹配时从选择返回空值
【发布时间】:2019-02-15 18:49:20
【问题描述】:

下面的控制台项目代码示例与我的代码类似; irl 更复杂,但我遇到的问题已得到充分证明。当 where 子句的一侧似乎与 foreach 循环中使用的表达式匹配以填充 where 子句的另一侧时,我无法理解为什么 Demo 方法中的 linq select 返回 null。

我已经尝试了相同代码的多种不同排列,但无论我做什么,我都在使用 null 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!"); }
            }
        }
    }
}

【问题讨论】:

    标签: c# linq dictionary null where


    【解决方案1】:

    因为您将 thisOrder 解释为错误的类型:

    as Dictionary<int, OrderLine>
    

    由于表达式的结果不是Dictionary&lt;int, OrderLine&gt;,因此尝试将其强制转换为一个的结果是null。结果是一个集合,甚至不是Dictionary&lt;int, OrderLine&gt; 对象,而是Dictionary&lt;int, OrderLine&gt;.ValueCollection 对象。 (一个包含一个元素的集合,但仍然是一个集合。)

    您可以从该集合中选择。例如,如果您想要的是Dictionary&lt;int, OrderLine&gt;

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

    总的来说,主要的一点是您的查询工作正常,但您告诉系统使用错误的类型。

    【讨论】:

    • 我之前还没有看到过错误转换导致 null 而不是错误的问题 - 我以后会注意的。总是“小”的东西!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-03
    • 2022-07-08
    • 2022-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多