将 Linq 查询结果转换为字典

Posted

技术标签:

【中文标题】将 Linq 查询结果转换为字典【英文标题】:Convert Linq Query Result to Dictionary 【发布时间】:2010-10-31 12:49:55 【问题描述】:

我想使用 Linq to SQL 向数据库添加一些行,但我想在添加行之前进行“自定义检查”以了解是否必须添加、替换或忽略传入的行。 我想保持客户端和数据库服务器之间的流量尽可能低,并尽量减少查询次数。

为此,我想获取验证所需的尽可能少的信息,并且只在流程开始时获取一次。

我正在考虑做这样的事情,但显然,它不起作用。有人有想法吗?

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

我最后想要的是一个字典,而不必从 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]);

【问题讨论】:

【参考方案1】:

尝试像这样使用the ToDictionary method:

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

【讨论】:

@pawan,它是枚举中每个元素的占位符,并采用枚举中对象的类型。 @pawan - 看起来不对。我希望var servers = list.Select( s =&gt; new s.ProjectName, Url = "tcp://" + s.BuildMachineName + ":" + s.PortNumber + "/CruiseManager.rem" ).ToDictionary( s =&gt; s.ProjectName, s.Url ); 这会创建一个以项目名称/url 对的项目名称为键的字典。 为什么.Select( t =&gt; new t.Key, t.TimeStamp ) 表达式是必要的? @BenCollins:我认为中间的.Select会导致生成的SQL只选择Key和TimeStamp,而不是选择每一列。 如果你正在使用 Linq to Object(而不是 Linq to SQL),你可以省略这个中介 Select【参考方案2】:

看看你的例子,我认为这就是你想要的:

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

【讨论】:

哇...可能就这么简单...由于我对编程很陌生,我会尝试一下并进行一些分析以确保在幕后,我不会获得整个对象的命中。我会及时通知你。 我刚刚完成了我的检查。可悲的是,在获取 TableObj 时,它从数据库中获取了所有对象,所以我最终得到了流量。我还检查了我发布的第二种方式(并希望避免)的查询,他们只得到了必要的项目。当然它会执行 2 次查询,因此服务器本身必须搜索两次表,但对象映射很简单。 你也许可以这样做:TableObj.Select(t => new t.Key, t.TimeStamp ).ToDictionary(t => t.Key, t => t.TimeStamp) ; LinqToSql 应该能够注意到您只想要两件事(来自选择)并返回它们。我不确定深入研究 ToDictionary() 的细节是否足够聪明。 不错!这是结果查询:SELECT [t0].[Key], [t0].[TimeStamp] FROM [TableObj] AS [t0]。我不想因此而受到赞扬,所以继续将其发布为anwser! :-P【参考方案3】:

试试下面的

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

或完全成熟的类型推断版本

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

【讨论】:

感谢 JaredPar 的回答。我教过类似的东西,但我认为这会返回 ObjType 类型的整个对象,并且我想避免下载整个对象。 @Tipx,你能提供一些关于你想要过滤的信息吗?添加过滤子句是可能的,但我无法从你的问题中看出什么是重要的 我只需要知道是否需要添加、忽略或替换另一行的“新行”就是对象的时间戳。数据库中的对象有很多我不需要验证的字段,我不想获得获取整个对象的性能影响。为了简单起见,我在我的 BD 中有一个包含 20 列、100 000 行的表,我想使用前 2 列的值提取字典。 我刚刚检查了该代码生成的服务器查询,您可能知道,它获取了整个对象。【参考方案4】:

使用命名空间

using System.Collections.Specialized;

创建DataContext 类的实例

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();

【讨论】:

对于 多个键 ?

以上是关于将 Linq 查询结果转换为字典的主要内容,如果未能解决你的问题,请参考以下文章

将两个查询的左外连接转换为 LINQ

使用 linq 将列表转换为字典,而不用担心重复

如何将以下 linq 查询转换为 SQL 中的 (Having)

Python中 将sqlalchemy中查询结果转换为字典

将 sql 查询转换为 linq 查询

将 SQL 转换为 Linq 查询