我喜欢将自己视为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
)
提前致谢。
答案 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() }