C#中的词典词典

时间:2016-12-07 23:31:23

标签: c# dictionary

我正在使用C#代码从SQl SERVER读取一个SQL表。

我的数据如下:

ZOO   Animal    Mn Tu
NDS     BAT     2   0
GOR     BAT     3   1
VTZ     BAT     1   2
MAS     BAT     0   0
CST     BAT     0   0
NDS     CAT     4   0
GOR     CAT     4   0
VTZ     CAT     2   0
MAS     CAT     7   0
CST     CAT     1   0
NDS     DOG     3   0
GOR     DOG     2   0
VTZ     DOG     1   0
MAS     DOG     3   0
CST     DOG     0   1
NDS     EGG     7   0
GOR     EGG     2   0
VTZ     EGG     0   0
MAS     EGG     0   0
CST     EGG     4   0

我写了一个sql reader命令,它就是

sql = "SELECT * FROM table";

OleDbCommand cmd = new OleDbCommand(sql, conn);
        cmd.CommandTimeout = 600;
        using (OleDbDataReader reader = cmd.ExecuteReader())
        {


            while (reader.Read())
            {
                var location = reader.GetString(0).Trim();
                var animal= reader.GetString(1).Trim();
                var Monday= reader.GetValue(1).ToString().Trim();
                var Tuesday= reader.GetValue(3).ToString().Trim();

             }
        }

我按如下方式创建了一个词典:

 private Dictionary<string, Dictionary<string, Dictionary<string, string>>> zooDict;
 zooDict= new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();

我希望有一个像这样的结构:

{
NDS:
    {
     BAT:
        {Mn: 2,
         Tu: 2},
     CAT:
        {
        MN: 4,
        Tu: 0
        }
     DOG:
        {
        MN: 3,
        Tu: 0
        }

     EGG:
        {
        MN: 7,
        Tu: 0
        }


    }
    GOR:
        .
        .
        .
        .
        .

}

我希望将此字典转换为json文件,但我无法将键和值添加到空字典中。我来自python背景,我可以使用defaultdict创建字典字典而不会遇到键错误。

任何创建字典的提示都将非常受欢迎。

if (!ZooDict.ContainsKey(location))
{
    var catDict = new Dictionary<string, string>();
    catDict.Add("Mon", Monday);
    catDict.Add("Tue", Tuesday);
    var AnimalDict = new Dictionary<string, Dictionary<string, string>>();
    AnimalDict.Add(animal, catDict);
    waitlistDict.Add(location, AnimalDict);
}
else
{
    if (!waitlistDict[location].ContainsKey(animal))
    {
        var catDict = new Dictionary<string, string>();
        catDict.Add("Mon", Monday);
        catDict.Add("Tue", Tuesday);
        var AnimalDict = new Dictionary<string, Dictionary<string, string>>();
        AnimalDict.Add(animal, catDict);
        waitlistDict[location] = AnimalDict;
    }
    else
    {
        if (waitlistDict[location][animal].ContainsKey("Mon"))
        {
            waitlistDict[location][animal]["Mon"] = Monday;
        }
        else
        {
            waitlistDict[location][animal]["Mon"] = Monday;
        }
        if (waitlistDict[location][animal].ContainsKey("Tue"))
        {
            waitlistDict[location][animal]["Tue"] = Tuesday;
        }
        else
        {
            waitlistDict[location][animal]["Tue"] = Tuesday;
        }
    }
}

2 个答案:

答案 0 :(得分:6)

您可以直接在循环中填写词典

private Dictionary<string, Dictionary<string, Dictionary<string, string>>> zooDict =
     new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();

while (reader.Read())
{
       var location = reader.GetString(0).Trim();
       var animal= reader.GetString(1).Trim();
       var Monday= reader.GetValue(1).ToString().Trim();
       var Tuesday= reader.GetValue(3).ToString().Trim();

       if(!zooDict.ContainsKey(location))
            zooDict[location] = new Dictionary<string, Dictionary<string, string>>();

       zooDict[location][animal] = new Dictionary<string, string>() 
       {
             { "MN", Monday },
             { "Tu", Tuesday }
       };
}

作为旁注,您可能需要考虑创建表示对象的类,将它们添加到字典或列表中,并使用Newtonsoft Json.net(http://www.newtonsoft.com/json)来序列化它们,而不是使用字典来表示所有内容。例如,您可以创建一个类:

public class Animal
{
     public string Name { get; set; }
     public int Monday { get; set; }
     public int Tuesday { get; set; }
}

var zooDict = new Dictionary<string, List<Animal>>();

// then in your while loop you do this 
if(!zooDict.ContainsKey(location))
    zooDict[location] = new List<Animal>();
zooDict[location].Add(new Animal() { /* fill Monday and Tuesday properties */ });

当然,您可以更进一步,创建一个包含属性string LocationList<Animal> Animals的类,并完全删除字典。这取决于你的使用案例我想

答案 1 :(得分:5)

public class DataLine
{
    public string Zoo { get; set; }
    public string Animal { get; set; }
    public int Mn { get; set; }
    public int Tu { get; set; }
}
public IEnumerable<DataLine> ReadAllLines()
{
    ...
    using (OleDbDataReader reader = cmd.ExecuteReader())
    {
        while (reader.Read())
        {
            yield return new DataLine() { Zoo = reader.GetString(0).Trim(), Animal = reader.GetString(1).Trim(), Mn = reader.GetInt32(2), Tu = reader.GetInt32(3) };
        }
    }
}
var dictionary = ReadAllLines()
    .GroupBy(line => line.Zoo)
    .ToDictionary(zoo => zoo.Key,
                  zoo => zoo.ToDictionary(animal => animal.Animal,
                                          animal => new { animal.Mn, animal.Tu }));

var sb = new StringBuilder();

using (var sw = new System.IO.StringWriter(sb))
{
    new Newtonsoft.Json.JsonSerializer().Serialize(sw, dictionary);
}

Console.WriteLine(sb.ToString());