将for循环转换为linq查询

问题描述:

我喜欢将自己认为与LINQ相当不错,但我偶尔会尝试完成某些我无法工作的东西。我想一个SPListItemCollection转换成字典,以便我可以使用该密钥来查找值,而不需要一个LINQ每次查询:将for循环转换为linq查询

var formsConfigItems = new Dictionary<string, string>(); 
foreach (SPListItem item in list.GetItems(query)) 
    formsConfigItems.Add(item.Title, (item["Value"] == null ? string.Empty : item["Value"].ToString())); 

这工作,但我希望做的一个更清洁的时尚,使用LINQ。 (没什么大不了的,但我喜欢使用LINQ在for循环只要有可能,虽然它的幕后同样的事情

我试图做这样的事情:

var formsConfigItems = (from SPListItem i in list.GetItems(query) 
         select new { i.Title, i["Value"].ToString() }).ToDictionary<string, string>(k=>k.Key, k=>k.Value); 

但是,没有按”不像是会工作,如果我尝试使用上list.GetItems(query) lambda表达式,我不给使用.Where期权或任何LINQ命令(这是奇怪的,因为它是一个SPListCollection

在此先感谢。

+0

“如果我尝试使用上list.GetItems(查询)lambda表达式,我不给选项使用“。返回类型是否实现IEnumerable ?如果不是,你需要调用list.GetItems(query).AsEnumerable()。 – 2013-03-08 14:58:49

试试:

var formsConfigItems = list.GetItems(query) 
          .Cast<SPListItem>() 
          .ToDictionary(item => item.Title, 
             item => Convert.ToString(item["Value"])); 

要回答您的疑问:

如果我尝试使用上list.GetItems lambda表达式(查询),我给使用。凡或任何LINQ的选择我不 命令(这是奇怪的 因为它是一个SPListCollection)

这是因为SPListCollection是一个“老派”的集合,实现IEnumerable但不IEnumerable<T>,所以C#/ LIN Q(无论如何在编译时)无法知道它包含的项目的类型Cast<SPListItem>()调用帮助解决此问题 - 它将IEnumerable变成IEnumerable<T>,允许在编译时解决类型代数问题。由于您明确指定了循环变量的类型,因此您的for循环没有此问题 - 编译器将为您的序列中的每个项目插入一个强制转换。

我试图做这样的事情(查询表达式)。但那 似乎并没有工作。

那是因为你没有正确构建匿名类型实例(属性名称不能推断任意表达式)和你的Lambda表达式是不完全正确或者(您使用属性名称不匹配匿名类型的属性名称)。试试这个:

var formsConfigItems = (from SPListItem i in list.GetItems(query) 
         select new 
         { 
          i.Title, 
          Value = Convert.ToString(i["Value"]) 
         }).ToDictionary(a => a.Title, a => a.Value); 
+0

用你的编辑打败我,大概24秒:) – 2013-03-08 15:09:03

+1

@Joe:干杯,我赞成你的因为额外的细节。 – Ani 2013-03-08 15:13:51

+0

谢谢大家。这非常有帮助 – 2013-03-08 16:21:41

阿尼的得到了更好的解决方案海事组织,但是你错过了一两件事:你的LINQ语句创建匿名项目的集合,但你不能在属性名给予匿名课程。

k=>k.Key表达不起作用,因为它不知道什么Key是 - 你只定义Title(因为你没有给它一个名称,它借鉴了对象中的一个)。 Value不能自动计算出来,所以会引发编译器错误。

要做到这种方式,你需要特别声明的名字:

new { Key = i.Title, Value = i["Value"].ToString() }