将for循环转换为linq查询
本文关键字:linq 查询 转换 for 循环 | 更新日期: 2023-09-27 18:02:52
我喜欢认为自己很擅长使用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而不是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
)
尝试:
var formsConfigItems = list.GetItems(query)
.Cast<SPListItem>()
.ToDictionary(item => item.Title,
item => Convert.ToString(item["Value"]));
回答您的问题:
如果我尝试在list.GetItems(query)上使用lambda表达式,我不是给出了使用.Where或任何linq命令的选项(这很奇怪)因为它是一个SPListCollection)
这是因为SPListCollection
是一个"老派"集合,实现了IEnumerable
而不是IEnumerable<T>
,所以c#/LINQ(无论如何在编译时)无法告诉它包含的类型项。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);
我有更好的解决方案,但是你还缺少另一件事:你的LINQ语句正在创建一个匿名项目的集合,但是你没有给匿名类中的属性命名。
k=>k.Key
表达式不起作用,因为它不知道Key
是什么——你只定义了Title
(因为你没有给它一个名字,它从对象中借用了一个名字)。Value
不能自动计算出来,所以它会抛出一个编译错误。
要这样做,您需要特别声明名称:
new { Key = i.Title, Value = i["Value"].ToString() }