C# 使用多个搜索键和值实现字典

C# 使用多个搜索键和值实现字典,c#,dictionary,data-structures,lookup,C#,Dictionary,Data Structures,Lookup,我在明细表中有一个40000行的列表,它的值基于五个键列。这张桌子看起来像这样- Date Location Schedule Id Type Lane Value 1/1/2019 Paris Sched - 1 Rural <null> 34.94 1/1/2019 Paris Sched - 1 Rural <null> 35.41 1/1/2019 Paris Sched - 1 Rur

我在明细表中有一个40000行的列表,它的值基于五个键列。这张桌子看起来像这样-

Date    Location    Schedule Id Type    Lane    Value
1/1/2019    Paris   Sched - 1   Rural   <null>  34.94
1/1/2019    Paris   Sched - 1   Rural   <null>  35.41
1/1/2019    Paris   Sched - 1   Rural    101    39.45
1/1/2019    Paris   Sched - 1   Urban    101    94.23
1/1/2019    Paris   Sched - 1   <null>   101    24.87
1/1/2019    Paris   Sched - 1   <null>  <null>  33.38
一个小的修正。我的意思是,它们可能有空值,但前5个键的组合仍然是唯一的

使用
字典
(假设值的类型为
double
),其中
ScheduleTableKey
是由所有键列组成的结构。您将获得接近O(1)的复杂性

例如:

struct ScheduleTableKey {
    DateTime Date;
    string   Location;
    string   Schedule_Id;
    string   Type;
    int?     Lane;
}

var table = new Dictionary<ScheduleTableKey, double>();
struct ScheduleTableKey{
日期时间日期;
字符串位置;
字符串调度Id;
字符串类型;
国际车道;
}
var table=newdictionary();

请注意,根据您的情况,不同类型的结构成员可能更合适。

字典将占用所有键和值的存储空间,但从40000条记录创建只需百分之一秒,并且可以让您非常高效地查找值

假设
src
是包含日程表的
IEnumerable
,则可以使用

var ValueMap = src.ToDictionary(s => new { s.Date, s.Location, s.ScheduleId, s.Type, s.Lane }, s => s.Value);
然后,可以使用以下选项查找值:

var k = new { Date, Location, ScheduleId, Type, Lane };
var value = ValueMap[k];
如果不知道明细表中是否存在特定的键,可以使用

if (ValueMap.TryGetValue(k, out var value)) {
    // use value here
}
else {
    // there is no matching value
}
如果可用(例如C#7),使用
ValueTuple
将更快地处理,并且在进行数百万次查找时不会产生垃圾(如果有必要的话)

var ValueMap = src.ToDictionary(s => (s.Date, s.Location, s.ScheduleId, s.Type, s.Lane), s => s.Value);

var k = (Date, Location, ScheduleId, Type, Lane);
var value = ValueMap[k];

字典只能有一个键,但这并不意味着键本身不能包含所需的任何不同属性…使用字典为什么不将其委托给具有适当索引的SQL数据库?
“处理数百万条记录”
--使用SQLYou声明Schedule表中这五个键的组合具有唯一的行,但是示例数据集中的前两行具有相同的键。那么,您的数据中是否存在重复项?这种结构不会起作用,因为他有重复项。它可能应该是一个
字典
,并且经常提到,如果您使用自定义类作为字典中的键,那么该类应该实现
IEquatable
,并重写
Equals
GetHashCode()
@ErikPhilips,他特别指出,5列键是唯一的:Schedule表中这五个键的组合有唯一的行。我认为他混淆了术语
unique
。他应该说有一个
,但从表的前两行可以清楚地看到,这是通过该键复制的。@ErikPhilips哦,并没有注意到这一点。我要求OP澄清。感谢Martineralecký,@ErikPhilips,我的意思是前5个键的组合是唯一的,其中最后两个键可能有空,我想知道如果我们创建一个具有前三个属性(日期、位置、日程Id)的键表,然后创建一个具有最后三个键属性(类型、土地、值)的项目列表会怎么样。这样,当找到键上的记录时,可以执行列表或线性搜索来找到适当的组合。一个问题是要知道建立这样一个字典需要多少时间才能使用,以及获取单个记录需要多少时间。
var ValueMap = src.ToDictionary(s => (s.Date, s.Location, s.ScheduleId, s.Type, s.Lane), s => s.Value);

var k = (Date, Location, ScheduleId, Type, Lane);
var value = ValueMap[k];