【问题标题】:Transform a DataTable into Dictionary C#将 DataTable 转换为字典 C#
【发布时间】:2013-11-11 20:08:14
【问题描述】:

我想知道如何将 DataTable 转换为 Dictionary。我做了这样的事情。

using System.Linq;

internal Dictionary<string,object> GetDict(DataTable dt)
{
    return dt.AsEnumerable()
      .ToDictionary<string, object>(row => row.Field<string>(0),
                                row => row.Field<object>(1));
}

但我明白了:

System.Data.EnumerableRowCollection 不包含“ToDictionary”的定义和最佳扩展方法重载“System.Linq.Parallel.Enumerable.ToDictionary(System.Linq.ParallelQuery, System.Func, System.Collections.Generic. IEqualityComparer)' 有一些无效的参数ch

我该如何解决这个问题?

谢谢

【问题讨论】:

  • 请发布完整的错误信息。
  • 我添加了完整的错误信息

标签: c# linq dictionary datatable enumerable


【解决方案1】:

我找到了解决方案,但不知道为什么。我编辑了我的问题,完成了代码,只是为了清楚我在做什么,然后我改成了这个

    internal Dictionary<string, object> GetDict(DataTable dt)
    {
        Dictionary<String, Object> dic = dt.AsEnumerable().ToDictionary(row => row.Field<String>(0), row => row.Field<Object>(1));
        return dic;
    }

【讨论】:

    【解决方案2】:

    ToDictionary 期望 IEnumberable&lt;T&gt; 作为第一种类型...您告诉它这是一个错误的字符串,它是 IEnumerable&lt;DataRow&gt;

    指定类型让你感到困惑...试试这个...

    internal Dictionary<string,object> GetDict(DataTable dt)
    {
        return dt.AsEnumerable()
          .ToDictionary(row => row.Field<string>(0),
                                    row => row.Field<object>(1));
    }
    

    【讨论】:

      【解决方案3】:

      我认为这会对你有所帮助:

                  DataTable dt = new DataTable();
                  dt.Columns.Add("Column1");
                  dt.Columns.Add("Column2");
                  dt.Rows.Add(1, "first");
                  dt.Rows.Add(2, "second");
                  var dictionary = dt.Rows.OfType<DataRow>().ToDictionary(d => d.Field<string>(0), v => v.Field<object>(1));
      

      【讨论】:

      • 编译器错误:“DataRow”不包含“Field”的定义,并且没有可访问的扩展方法“Field”接受...
      • 需要在.NET Core中安装System.Data.DataSetExtensions.dll,都不错
      【解决方案4】:

      泛型方法ToDictionary 有3 个参数。你离开了一个,所以它不知道该怎么办。如果要指定所有参数,则为&lt;DataRow, string, object&gt;

      internal Dictionary<string,object> GetDict(DataTable dt)
      {
          return dt.AsEnumerable()
            .ToDictionary<DataRow, string, object>(row => row.Field<string>(0),
                                      row => row.Field<object>(1));
      }
      

      当然,如果你不使用它们,编译器可以推断类型,所以你不会得到错误。

      【讨论】:

      • +1,是的,这是主要原因,更多详情ToDictionary<TSource, TKey, TElement>
      • @Ilaria 您必须以一种或另一种方式将其转换为可枚举,否则您无法使用 Linq。另一种方法是dt.Rows.Cast&lt;DataTable&gt;()
      【解决方案5】:

      所有之前的答案都没有帮助我,所以我这样做了:

      myList = dt.AsEnumerable()
      .ToDictionary<DataRow, string, string>(row => row[0].ToString(),
                                             row => row[1].ToString()); 
      

      效果很好!

      【讨论】:

        【解决方案6】:

        我更喜欢这种方法:

        public static List<Dictionary<string, string>> GetDataTableDictionaryList(DataTable dt)
        {
            return dt.AsEnumerable().Select(
                row => dt.Columns.Cast<DataColumn>().ToDictionary(
                    column => column.ColumnName,
                    column => row[column].ToString()
                )).ToList();
        }
        

        之所以如此,是因为这段代码还可以通过调用ToString方法来处理布尔值或其他数据类型。

        请注意,这会返回一个字典列表,如果您有每一行的键,您可以将其修改为字典字典。

        遍历 bool 列可能如下所示:

        var list = GetDataTableDictionaryList(dt);
        
        foreach (var row in list)
        {
            if (row["Selected"].Equals("true", StringComparison.OrdinalIgnoreCase))
            {
                // do something
            }
        }
        

        【讨论】:

          【解决方案7】:

          给定的解决方案假设只有 2 列。 如果你想要多列表示,你需要一个字典列表

          class Program
          {
              static void Main(string[] args)
              {
                  DataTable dt = new DataTable();
                  dt.Columns.Add("Column1");
                  dt.Columns.Add("Column2");
                  dt.Columns.Add("Column3");
                  dt.Rows.Add(1, "first", "A");
                  dt.Rows.Add(2, "second", "B");
          
                  var dictTable = DataTableToDictionaryList(dt);
                  var rowCount = dictTable.Count;
                  var colCount = dictTable[0].Count;
          
                  //Linq version
                  var dictTableFromLinq = dt.AsEnumerable().Select(
                          // ...then iterate through the columns...  
                          row => dt.Columns.Cast<DataColumn>().ToDictionary(
                              // ...and find the key value pairs for the dictionary  
                              column => column.ColumnName,    // Key  
                              column => row[column] as string // Value  
                              )
                          ).ToList();
              }
          
              public static List<Dictionary<string, object>> DataTableToDictionaryList(DataTable dt)
              {
                  var result = new List<Dictionary<string, object>>();
                  //or var result = new List<Dictionary<string, string>>();
          
                  foreach (DataRow row in dt.Rows)
                  {
                      var dictRow = new Dictionary<string, object>();
                      foreach (DataColumn col in dt.Columns)
                      {
                          dictRow.Add(col.ColumnName, row[col]);
                          //or dictRow.Add(col.ColumnName, row[col].ToString());
                      }
          
                      result.Add(dictRow);
                  }
          
                  return result;
              }
          }  
          

          【讨论】:

            【解决方案8】:

            视觉基础
            使用sql加载数据表并创建字典

                Dim SalesRep As New System.Collections.Generic.Dictionary(Of String, String)(StringComparer.InvariantCultureIgnoreCase)
                Using tbl As New Data.DataTable("SalesRep")
                    SqlCommand.CommandText = "Select Initial,FullName from QB_SalesRep"
                    tbl.Load(SqlCommand.ExecuteReader())
                    ' --- Option ONE use the array to iterate
                    Array.ForEach(tbl.Rows.Cast(Of Data.DataRow).ToArray(),
                                  Sub(f)
                                      SalesRep.Add(f.ItemAsString("Initial"), f.ItemAsString("FullName"))
                                  End Sub)
                    ' --- Option TWO use plain linq to create the dictionary
                    SalesRep = tbl.Rows _
                        .Cast(Of Data.DataRow) _
                        .AsEnumerable() _
                        .ToDictionary(Function(f) f.Item("Initial").toString(), Function(f) f.Item("FullName").toString)
                End Using
            

            【讨论】:

              猜你喜欢
              • 2019-09-15
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-11-17
              • 2014-09-02
              • 2021-09-28
              • 2021-06-06
              相关资源
              最近更新 更多