如何编写一个导致字典的LINQ查询?

public class Person { public string NickName{ get; set; } public string Name{ get; set; } } var pl = new List<Person>; var q = from p in pl where p.Name.First() == 'A' orderby p.NickName select new KeyValuePair<String, String>(p.NickName, p.Name); var d1 = q.ToList(); // Gives List<KeyValuePair<string, string>> var d2 = q.ToDictionary(); // Does not compile 

如何获得词典<string,string>?

您需要指定Dictionary的值

 var d2 = q.ToDictionary(p => p.NickName, p => p.Name); 

字典不能包含多个相等的密钥,所以你应该确保(或者知道)情况并非如此。 你可以使用GroupBy来确保它:

 Dictionary<string, string> dict = pl .Where(p => p.Name.First() == 'A') .GroupBy(p => p.NickName) .ToDictionary(g => g.Key, g => g.First().Name); 

编辑

如果你真的觉得你需要隐式地从IEnumerable<KeyValuePair<TKey, TValue>>到一个Dictionary你可以添加这个扩展。

 public static IDictionary<TKey, ToValue> ToDictionary<TKey, TValue>( this IEnumerable<KeyValuePair<TKey, TValue>> source) { return source.ToDictionary(p => p.Key, p => p.Value); } 

然后,您可以在任何IEnumerable<KeyValuePair<TKey, TValue>>上调用ToDictionary()

编辑2

如果您预计重复,那么您也可以创build一个ToLookup()扩展。

 public static ILookup<TKey, TValue> ToLookup<TKey, TValue>( this IEnumerable<KeyValuePair<TKey, TValue>> source) { return source.ToLookup(p => p.Key, p => p.Value); } 

或者,如果您确实想放弃结果,则可以为ToDictionary添加一个重载。

 public static IDictionary<TKey, ToValue> ToDictionary<TKey, TValue>( this IEnumerable<KeyValuePair<TKey, TValue>> source, Func<<IEnumerable<TValue>, TValue> selector) { return source .Lookup(p => p.Key, p => p.Value); .ToDictionary(l => l.Key, l => selector(l)); } 

如果你任意丢弃除“第一”(这是什么意思没有OrderBy )项目的所有,你可以使用这样的扩展,

 pairs.ToDictionary(v => v.First()); 

总的来说,你可以删除大部分的代码,

 var q = from p in pl where p.Name.First() == 'A'; var d = q.ToDictionary(p => p.NickName, p => p.Name); 

如果可能有重复, 请执行

 var d = q.ToLookup(p => p.NickName, p => p.Name); 

但是请注意,这将返回一个ILookup<TKey, TElement> ,它的Item索引器将返回一个IEnumerable<TElement>所以您不会丢弃数据。

尝试关注NickName作为关键字,并将其命名为Value

 var d2 = q.ToDictionary (p => p.NickName, p=>p.Name); 

但是请注意,字典不允许重复,所以上面的将重复logging相同的绰号的错误。 也许你想使用类似于字典的查找,但允许重复

 var d2 = q.ToLookup (p => p.NickName, p=>p.Name); 

我意识到这是用c#标记的,但是我实际上只是想知道如何在vb.net中做到这一点,所以我想我会分享你如何在VB中做到这一点:

 Public Class Person Property NickName As String Property Name As String End Class Sub Main() Dim p1 As New List(Of Person) '*** Fill the list here *** Dim q = (From p In p1 Where p.Name.First = "A" Select p.NickName, p.Name).ToDictionary( Function(k) k.NickName, Function(v) v.Name) End Sub