将Linq查询结果转换为字典


346

我想使用Linq to SQL向数据库中添加一些行,但是我想在添加行之前进行“自定义检查”,以了解是否必须添加,替换或忽略传入的行。我想尽量减少客户端和数据库服务器之间的通信量,并最大程度地减少查询数量。

为此,我希望获取验证所需的尽可能少的信息,并且在过程开始时仅获取一次。

我当时正在考虑做这样的事情,但是显然,这是行不通的。有人有主意吗?

Dictionary<int, DateTime> existingItems = 
    (from ObjType ot in TableObj
        select (new KeyValuePair<int, DateTime>(ot.Key, ot.TimeStamp))
    )

我最后想要的是一个Dictionary,而不必从TableObject下载整个ObjectType对象。

我还考虑了以下代码,但是我试图找到一种正确的方法:

List<int> keys = (from ObjType ot in TableObj orderby ot.Key select ot.Key).ToList<int>();
List<DateTime> values = (from ObjType ot in TableObj orderby ot.Key select ot.Value).ToList<int>();
Dictionary<int, DateTime> existingItems = new Dictionary<int, DateTime>(keys.Count);
for (int i = 0; i < keys.Count; i++)
{
    existingItems.Add(keys[i], values[i]);
}

Answers:


632

尝试使用如下ToDictionary方法

var dict = TableObj.ToDictionary( t => t.Key, t => t.TimeStamp );

2
@pawan,它是枚举中每个元素的占位符,并采用枚举中对象的类型。
tvanfosson 2011年

1
@pawan-看起来不正确。我希望var servers = list.Select( s => new { s.ProjectName, Url = "tcp://" + s.BuildMachineName + ":" + s.PortNumber + "/CruiseManager.rem" } ).ToDictionary( s => s.ProjectName, s.Url ); 这会创建一个由项目名称/ URL对的项目名称作为关键字的字典。
tvanfosson 2011年

3
为什么.Select( t => new { t.Key, t.TimeStamp } )需要表达?
Ben Collins

9
@BenCollins:我认为中间层.Select会导致生成的SQL仅选择Key和TimeStamp,而不是选择每一列。
2014年

1
Select如果您正在对对象执行Linq(而不是对SQL的Linq),则可以忽略此中介
Pac0

119

查看您的示例,我认为这是您想要的:

var dict = TableObj.ToDictionary(t => t.Key, t=> t.TimeStamp);

哇...可能就这么简单...由于我是编程新手,因此我将尝试并做一些剖析,以确保在幕后我不会受到整个对象的打击。我会及时向大家发布。
Tipx

1
我刚查了一下。可悲的是,在获取TableObj的同时,它从数据库中获取了所有对象,因此最终导致了交通拥堵。我还检查了第二种方式发布的查询(并希望避免这种查询),它们仅获得必要的项目。当然,它会执行2个查询,因此服务器本身必须搜索两次表,但是对象映射足够简单。
Tipx

7
您可能可以执行以下操作:TableObj.Select(t => new {t.Key,t.TimeStamp})。ToDictionary(t => t.Key,t => t.TimeStamp); LinqToSql应该能够注意到您只想要两件事(来自select)并返回它们。我不确定它是否足够聪明以深入研究ToDictionary()的细节。
Talljoe

1
不错!这是结果查询:SELECT [t0]。[Key],[t0]。[TimeStamp]从[TableObj] AS [t0]。我不想为此付出功劳,因此请继续将其张贴为答案!:-P
Tipx

8

尝试以下

Dictionary<int, DateTime> existingItems = 
    (from ObjType ot in TableObj).ToDictionary(x => x.Key);

或完全类型推断的版本

var existingItems = TableObj.ToDictionary(x => x.Key);

感谢您的JaredPar。我教过类似的东西,但是我认为这将返回ObjType类型的整个对象,并且我希望避免下载整个对象。
Tipx

@Tipx,您能否提供一些有关要筛选的内容的信息?可以添加过滤器子句,但是我不能从您的问题中看出什么是重要的
JaredPar 2009年

我需要知道的是是否需要添加,忽略或替换“新行”是对象的时间戳。数据库中的对象有很多字段,我不需要进行验证,也不想获得整个对象的性能下降。为简单起见,我在BD中有一个表,其中有20列,100 000行,并且我想使用前2列的值提取一个Dictionary。
Tipx

我刚刚检查了由该代码生成的服务器查询,并且您可能知道,它获取了整个对象。
Tipx

0

使用名称空间

using System.Collections.Specialized;

制作DataContextClass的实例

LinqToSqlDataContext dc = new LinqToSqlDataContext();

采用

OrderedDictionary dict = dc.TableName.ToDictionary(d => d.key, d => d.value);

为了检索值,请使用名称空间

   using System.Collections;

ICollection keyCollections = dict.Keys;
ICOllection valueCollections = dict.Values;

String[] myKeys = new String[dict.Count];
String[] myValues = new String[dict.Count];

keyCollections.CopyTo(myKeys,0);
valueCollections.CopyTo(myValues,0);

for(int i=0; i<dict.Count; i++)
{
Console.WriteLine("Key: " + myKeys[i] + "Value: " + myValues[i]);
}
Console.ReadKey();

对于多键
Kiquenet
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.