【问题标题】:C# DataTable to Dictionary with multiple valuesC# DataTable 到具有多个值的字典
【发布时间】:2018-03-05 13:23:52
【问题描述】:

我有一个 DataTable,它返回如下数据:

APP | VERSION
____|________  
app1| 1.0
app1| 2.0
app1| 3.0
app2| 1.0
app3|  

如您所见,“app1”有多个版本,有些应用没有任何版本。我需要将此数据表结果存储在某种列表中以供以后在我的代码中使用,所以我想出了字典,但无法让它工作。这是我尝试过的:

    public static Dictionary<string, List<string>> AppVer()
        {
         string SQL = "SELECT column1, column2 FROM myTable a LEFT JOIN 
         myTable2 v ON v.ID_FK=a.ID_PK";
         Dictionary<string, List<string>> versions = new Dictionary<string, 
         List<string>>();

         DataTable dt = new DataTable();

            try
            {
                using (var conn = new OracleConnection(conn_string))
                {
                    conn.Open();

                    using (OracleCommand cmd = new OracleCommand(SQL, conn))
                    {
                        using (OracleDataAdapter dad = new OracleDataAdapter(cmd))
                        {
                            dad.Fill(dt);
                        }
                        versions = dt.AsEnumerable().ToDictionary<DataRow, string, List<string>>(row => row[0].ToString(), new List<string>(row=> row[1].ToString()));
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
             return versions;
        }

但是,我得到错误

"无法将 lambda 表达式转换为类型 'string',因为它不是 委托类型”。

如何将我的 DataTable 存储到字典中?

编辑:

 Dictionary<string, List<Version>> all_versions =  AppVer();

            StringBuilder sb = new StringBuilder();

            foreach (var item in all_versions)
            {
                sb.AppendFormat("{0} - {1}{2}", item.Key, item.Value, Environment.NewLine);
            }

            string result = sb.ToString().TrimEnd();
            MessageBox.Show(result);

【问题讨论】:

  • 顺便说一句,你知道有一个Version-class 可以使用吗?所以我更喜欢Dictionary&lt;string, List&lt;Version&gt;&gt;
  • 您可能想查看.ToLookup,它与 ToDictionary 非常相似,但用于相同键的重复值时。 msdn.microsoft.com/en-us/library/…
  • @Chris,谢谢,你有什么例子吗,我找不到合适的?
  • @TimSchmelter,从来没有这样做过,我不太清楚为什么要为相同的数据运行两次数据库连接。如果这就是您所说的“版本”类的意思。

标签: c# dictionary datatable


【解决方案1】:
ILookup<string, string> myLookup = dt.AsEnumerable().ToLookup(row => row[0].ToString(), row => row[1].ToString());

IEnumerable<string> myValues = myLookup["app1"];

// Loop through lookup.
foreach(var group in myLookup)
{
    string key = group.Key;
    IEnumerable<string> myValues = group;

    Console.WriteLine("Group {0} has {1} elements", key, myValues);
}

【讨论】:

  • 感谢您的回答。但是我怎么能根据一个键循环值呢?
  • @Lucy82:我刚刚对答案进行了小幅编辑,以便更清楚地表明第二行正在获取数据(我希望你不介意,kara)。那时你有一个IEnumerable&lt;string&gt;,它将包含你所有不同的版本,你可以像任何其他IEnumerable一样循环。
  • @kara 和克里斯,感谢您的回答。我也喜欢这个,但蒂姆首先回答了,所以我希望你不介意;)
  • @Chris 谢谢! Lucy82:我在示例中添加了一个 foreach 循环。
  • @Lucy82:您完全可以选择接受哪个答案。 :)
【解决方案2】:

您需要按键GroupBy,然后您可以在群组上使用ToList。你知道有一个可以使用的Version-class 吗?所以我更喜欢Dictionary&lt;string, List&lt;Version&gt;&gt;:

public static Dictionary<string, List<Version>> AppVer()
{
    Dictionary<string, List<Version>> versions = null;
    string SQL = "SELECT column1, column2 FROM myTable a LEFT JOIN myTable2 v ON v.ID_FK = a.ID_PK";
    var dt = new DataTable();

    try
    {
        using (var conn = new OracleConnection(conn_string))
        using (var da = new OracleDataAdapter(SQL, conn))
        {
            da.Fill(dt);
        }

        versions = dt.AsEnumerable()
            .GroupBy(r => r.Field<string>(0))
            .ToDictionary(
                g => g.Key, 
                g => g.Select(r => Version.Parse(r.Field<string>(1))).ToList());
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }

    return versions;
}

Version 类的一个好处是它可以正确排序,所以10.12.1 之后。

【讨论】:

  • 感谢您。我让它正常工作,但我现在如何循环值?请参阅我编辑的问题,这不起作用。
  • @Lucy82:Value 现在是List&lt;Version&gt;,所以你可以使用sb.AppendFormat("{0} - {1}{2}", item.Key, String.Join(",",item.Value), Environment.NewLine);。这将用逗号连接每个应用程序版本。如果您想要不同的分隔符,请相应更改String.Join 的第一个参数。
  • 感谢您的回答。我接受它是因为你是第一个 :)
猜你喜欢
  • 1970-01-01
  • 2019-02-14
  • 2015-11-27
  • 1970-01-01
  • 1970-01-01
  • 2021-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多