2016-09-23 132 views
2

我一直在寻找这里,我意识到类似的问题之前已经问过,我已经过了几个,但似乎是正确的似乎没有工作。c#字典从关键字选择值

我有以下方法,它从SQL查询中收集的DataSet中提取一组键值对。

public static Dictionary<string, string> LoadConfiguration() 
    { 
     DataSet sqlResults = data.GetSettings(); 

     Dictionary<string, string> dict = 
      new Dictionary<String, String>(); 

     foreach (DataRow dr in sqlResults.Tables[0].Rows) 
     { 
      dict.Add(
       dr.Field<string>("key"), dr.Field<string>("value") 
        ); 
     } 

     return dict; 
    } 

这是因为,据我所看到得那样简单,但我从来没有真正借助词典之前,我是比较新的任何一种真正的编程打交道。

我知道,我的字典里所预期的数据,因为如果我遍历它在foreach,它给了我预期的结果

foreach (KeyValuePair<string, string> i in MyStuff.Configuration.LoadConfiguration()) 
    { 
     Console.WriteLine("Key = " + i.Key + " Value = " + i.Value); 
    } 

这给了我这是所有我实现了所以下面远

重点= EnableLdap值=假 重点= LdapPath值= LDAP:// DC =一些,DC =域,DC = com的 重点= SessionTimeout值= 60

但我只想从名为EnableLdap的密钥中选择一个特定值,例如

我的理解是,以下两种方法都是正确的。但是,当我尝试这种方式,我得到一个KeyNotFoundException

Dictionary<string,string> dict = MyStuff.Configuration.LoadConfiguration(); 
    Console.WriteLine(dict["EnableLdap"]); 

如果我试试这个,我收到了[出现InvalidOperationException:序列中没有匹配的元素]

Dictionary<string,string> dict = MyStuff.Configuration.LoadConfiguration(); 
    Console.WriteLine(dict.Single(s => s.Key == "EnableLdap").Value); 

如果我尝试这个,我刚刚得到什么

string value = ""; 

    if (dict.TryGetValue("EnableLdap", out value)) 
    { 
     dict["EnableLdap"] = value; 
     Console.WriteLine(value); 

    } 

我敢肯定,我失去了一些东西简单在这里,答案将导致捂脸

SOLUTION:

我被后面的空格所捕获,就像在评论中建议的那样。解决方案是简单地添加一些修剪到我的行值,当它们添加到我的词典。

public static Dictionary<string, string> LoadConfiguration() 
{ 
    DataSet sqlResults = data.GetSettings(); 

    Dictionary<string, string> dict = 
     new Dictionary<String, String>(); 

    foreach (DataRow dr in sqlResults.Tables[0].Rows) 
    { 
     dict.Add(
      dr.Field<string>("key").Trim(), dr.Field<string>("value").Trim() 
       ); 
    } 

    return dict; 
} 
+0

所以当迭代所有的结果,你看到输出'键= EnableLdap值= ...'? –

+3

我强烈怀疑你没有“EnableLdap”作为关键字,但看起来*非常相似*。尝试打印出每个键的长度,当你迭代它时......你可能会发现里面有空白或不可见的字符。 –

+0

可能有助于显示来自foreach循环的输出。它可能只是拼写错误? – code11

回答

4

它是这两个问题之一。

  1. 字典中不存在该键,这可能是由于拼写错误或者甚至是前导/尾随空格或某种性质。
  2. 关键是存在,但有不同的想法。

对于选项2,您可以通过在字典中提供StringComparer作为构造函数中的参数来确保套管不是问题。

Dictionary<string, string> dict = new Dictionary<String, String>(StringComparer.OrdinalIgnoreCase); 

上述代码片断将确保字典基于字符串键的序号不区分大小写形式为每个键创建散列。这将允许以下示例通过:

dict["enableldap"] = "true"; 
Console.WriteLine(dict["EnableLdap"]); 

有关更多选项,请参见StringComparer

+1

它尾随的空格。 –

+0

@SergeHarrison - 很高兴你的工作!为了安全起见,您可以使用'Trim'来添加您的密钥,以确保它不是问题。 ('dr.Field (“key”)。Trim()') – Igor

+1

这就是我最终做的。我不知道为什么SQL查询正在返回我的DataSet中的尾随空格,但这绝对可以解决当前的问题。 –

0

我的理解是,以下两种方法都是正确的。但是当我尝试这种方式时,我得到一个KeyNotFoundException

看来你的字典没有那个键。请记住,词典都可以使用这种方法,如果一个键存在检查重点敏感:

Console.WriteLine("Exist key "+ dict.ContainsKey("EnableLdap")); 

如果我试试这个,我收到了[出现InvalidOperationException:序列中没有匹配的元素]

Dictionary<string,string> dict = MyStuff.Configuration.LoadConfiguration(); 
    Console.WriteLine(dict.Single(s => s.Key == "EnableLdap").Value); 

linQ方法.Single期望找到一个值。如果没有发现该值将抛出异常。如果你不想要这个异常,你应该使用.SingleOrDefault,但要小心空值。

如果我尝试这个,我什么也没得到

TryGetValue不会抛出任何异常。它只是尝试。

我建议你在创建字典时为你的密钥添加大写或小写的格式。

foreach (DataRow dr in sqlResults.Tables[0].Rows) 
     { 
      dict.Add(
       dr.Field<string>("key").ToUpperCase(), dr.Field<string>("value") 
        ); 
     } 

,然后你不能查询它像这样:

if(dict.ContainsKey("ENABLELDAP")) 
{ 
    string value = dict["ENABLELDAP"]; 
}