将for循环转换为linq查询

时间:2013-03-08 14:54:20

标签: c# .net linq

我喜欢将自己视为LINQ非常好,但我时不时地尝试完成一些我无法工作的东西。我想将SPListItemCollection转换为字典,这样我就可以使用密钥来查找值,而不需要每次都需要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 over 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

提前致谢。

2 个答案:

答案 0 :(得分:7)

尝试:

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

回答您的疑问:

  

如果我尝试在list.GetItems(查询)上使用lambda表达式,我不是   给出了使用.Where或任何linq命令的选项(这很奇怪   因为它是一个SPListCollection)

那是因为SPListCollection是一个实现IEnumerable而不是IEnumerable<T>的“老派”集合,所以C#/ LINQ(无论如何编译时)都无法分辨出什么< em> 它包含的项目。 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);

答案 1 :(得分:2)

Ani获得了更好的IMO解决方案,但另外还有一件事:你的LINQ语句正在创建一个匿名项集合,但是你没有给那个匿名类中的属性命名。

k=>k.Key表达式不起作用,因为它不知道Key是什么 - 您只定义了Title(因为您没有给它命名,它从对象中借用了一个)。 Value无法自动计算,因此会引发编译错误。

要这样做,您需要专门声明名称:

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