2016-09-23 7 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値= falseを キー= LdapPath値= LDAP:// DCは、いくつかの、DC =ドメイン、DC = comの キー=あるSessionTimeout値= 60

を=

しかし、私は唯一例えばEnableLdapという名前のキーから特定の値を選択します

私の理解では、次の方法の両方が正しいだろうということです。

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

:[シーケンスが一致する要素が含まれていないと、InvalidOperationException]そして、私はこれをしようと私は何を取得、私はこの方法を試したときに、私はこれをしようとした場合でも、私はKeyNotFoundException

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

を得る私が取得します

string value = ""; 

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

    } 

私はここに簡単な何かが欠けていますかなり確信していると答えが手のひらを顔に当てる

になります

解決策:

コメントに数回示唆されたように、後続のスペースでキャッチしました。解決策は、私の辞書にそれらを追加するときに単に行の値にトリムを追加することでした。

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

? –

+3

"EnableLdap"をキーとして持っているのではないと思っていますが、非常に似ているようです。それを繰り返すときに各キーの長さを印刷してみてください...そこに空白や不可視文字のようなものがあるかもしれません。 –

+0

foreachループからの出力を表示するのに役立ちます。あなたは単にスペルミスをしている可能性がありますか? – code11

答えて

4

これらの2つの問題の1つです。

  1. キーが辞書に存在しません。これはスペルミスや先行/後ろのスペースなどのためです。
  2. キーは存在しますが、それはあなたとは異なるケースがあります。

コンシューマの引数として辞書にStringComparerを指定すると、オプション2の場合でも問題がないことが保証されます。

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クエリがなぜデータセット内の末尾のスペースを返すのかはわかりませんが、それは間違いなく即時の問題を解決します。 –

0

私の理解は、以下の両方の方法が正しいことです。しかし、この方法で試してみると、KeyNotFoundExceptionが発生します。

辞書にそのキーがないようです。

Dictionary<string,string> dict = MyStuff.Configuration.LoadConfiguration(); 
    Console.WriteLine(dict.Single(s => s.Key == "EnableLdap").Value); 
:私はこれをしようとした場合

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

私は[シーケンスが一致する要素が含まれていないと、InvalidOperationException]を取得する:辞書は、この方法を用いることにより、キーが存在かどうかをチェックすることができ、キーと小文字が区別されることに注意してください

linQメソッド.Singleは、値を見つけることを想定しています。値が見つからない場合、例外がスローされます。あなたはその例外を望まないなら、nullを気にするならば.SingleOrDefaultを使うべきです。

これを試しても、何も得られません。

TryGetValueは例外をスローしません。それはただ試みる。

辞書を作成するときに、大文字または小文字のいずれかのキーの書式を追加することをお勧めします。

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

、その後、あなたはこのようにそれを照会することはできません。すべての結果を反復処理するときに、あなたが出力 `キー= EnableLdap値を= ...`ご覧ください

if(dict.ContainsKey("ENABLELDAP")) 
{ 
    string value = dict["ENABLELDAP"]; 
} 
関連する問題