C# Dictionary of Dictionaries returns 来自 select 的空值在键引用上匹配时
C# Dictionary of Dictionaries returns null value from select when matched on key reference
下面的控制台项目代码示例与我的代码类似; irl 有更多的复杂性,但我遇到的问题已得到充分证明。我不明白为什么当 where<> 子句的一侧似乎与 foreach 循环中用于填充 where 另一侧的表达式匹配时,Demo 方法 return 中的 linq select 为 null <> 子句。
我已经尝试了相同代码的大量不同排列,但无论我做什么,我都在使用 null thisOrder
;我似乎无法超越它来处理任何事情。
我错过了什么;为什么我的 where 子句不是 return 订单字典内部字典中的订单?
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!"); }
}
}
}
}
因为您将 thisOrder
解释为错误的类型:
as Dictionary<int, OrderLine>
由于表达式的结果不是 Dictionary<int, OrderLine>
,尝试将其转换为 1 的结果是 null
。结果是 collection,甚至不是 Dictionary<int, OrderLine>
objects,而是 Dictionary<int, OrderLine>.ValueCollection
objects。 (一个 collection 包含一个元素,但 collection 仍然包含一个元素。)
你可以select从到collection。例如,如果您想要的是 Dictionary<int, OrderLine>
:
var thisOrder = (from l in myDepot.Orders
where l.Key.Reference == oRef
select l.Value).FirstOrDefault();
总体而言,要点是您的查询工作正常,但您告诉系统使用错误的类型。
下面的控制台项目代码示例与我的代码类似; irl 有更多的复杂性,但我遇到的问题已得到充分证明。我不明白为什么当 where<> 子句的一侧似乎与 foreach 循环中用于填充 where 另一侧的表达式匹配时,Demo 方法 return 中的 linq select 为 null <> 子句。
我已经尝试了相同代码的大量不同排列,但无论我做什么,我都在使用 null thisOrder
;我似乎无法超越它来处理任何事情。
我错过了什么;为什么我的 where 子句不是 return 订单字典内部字典中的订单?
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!"); }
}
}
}
}
因为您将 thisOrder
解释为错误的类型:
as Dictionary<int, OrderLine>
由于表达式的结果不是 Dictionary<int, OrderLine>
,尝试将其转换为 1 的结果是 null
。结果是 collection,甚至不是 Dictionary<int, OrderLine>
objects,而是 Dictionary<int, OrderLine>.ValueCollection
objects。 (一个 collection 包含一个元素,但 collection 仍然包含一个元素。)
你可以select从到collection。例如,如果您想要的是 Dictionary<int, OrderLine>
:
var thisOrder = (from l in myDepot.Orders
where l.Key.Reference == oRef
select l.Value).FirstOrDefault();
总体而言,要点是您的查询工作正常,但您告诉系统使用错误的类型。