【问题标题】:Select distinct values from a large DataTable column从大型 DataTable 列中选择不同的值
【发布时间】:2013-07-02 05:18:18
【问题描述】:

我有一个包含 22 列的 DataTable,其中一列称为“id”。我想查询此列并将所有不同的值保留在列表中。该表可以有 10 到 100 万行。

最好的方法是什么?目前,我正在使用 for 循环遍历列并比较值,如果值相同,则进入下一个,当不相同时,它将 id 添加到数组中。但是由于表可以有 10 到 100 万行,有没有更有效的方法来做到这一点!我将如何更有效地做到这一点?

【问题讨论】:

  • 你想得到不同的id吗
  • 那么,您在 DataTable 或数据库表中保留了 1000 万行?
  • 如果你有一个数据表,最好的办法是在取回数据表之前在数据库上执行此操作 - 它将能够非常有效地执行此操作,特别是如果 ID 是索引列。您也没有说数据是否按 ID 列排序。
  • 如何构建数据表?

标签: c# datatable


【解决方案1】:

这将返回您不同的 ID

 var distinctIds = datatable.AsEnumerable()
                    .Select(s=> new {
                        id = s.Field<string>("id"),                           
                     })
                    .Distinct().ToList();

【讨论】:

  • 完美,我认为这个答案是最灵活的。谢谢拉吉夫
  • 太棒了!使用数据表列出并使用 linq 进行区分...
【解决方案2】:

dt- 你的数据表名

ColumnName- 你的列名,即 id

DataView view = new DataView(dt);
DataTable distinctValues = new DataTable();
distinctValues = view.ToTable(true, ColumnName);

【讨论】:

  • 这确实会减少到不同的值 - 您的代码中的哪个方法负责减少到不同的值?
  • view.ToTable 是方法,将第一个参数设置为 true 获取所有不同的值。
  • 非常好——我用过这个。发布了。
  • 您可以省略第二行(在较新的 C# 语法中): var view = new DataView(dt); var distinctValues = view.ToTable(true, ColumnName);您可能还希望通过在创建 DataView 对象之前或期间设置 DataViews Sort 属性对不同的值进行排序: var view = new DataView(dt) { Sort = "columnName" };
【解决方案3】:

试试这个:

var idColumn="id";
var list = dt.DefaultView
    .ToTable(true, idColumn)
    .Rows
    .Cast<DataRow>()
    .Select(row => row[idColumn])
    .ToList();

【讨论】:

    【解决方案4】:

    方法一:

       DataView view = new DataView(table);
       DataTable distinctValues = view.ToTable(true, "id");
    

    方法二: 您必须创建一个与您的数据表列名称匹配的类,然后您可以使用以下扩展方法将 Datatable 转换为 List

        public static List<T> ToList<T>(this DataTable table) where T : new()
        {
            List<PropertyInfo> properties = typeof(T).GetProperties().ToList();
            List<T> result = new List<T>();
    
            foreach (var row in table.Rows)
            {
                var item = CreateItemFromRow<T>((DataRow)row, properties);
                result.Add(item);
            }
    
            return result;
        }
    
        private static T CreateItemFromRow<T>(DataRow row, List<PropertyInfo> properties) where T : new()
        {
            T item = new T();
            foreach (var property in properties)
            {
                if (row.Table.Columns.Contains(property.Name))
                {
                    if (row[property.Name] != DBNull.Value)
                        property.SetValue(item, row[property.Name], null);
                }
            }
            return item;
        }
    

    然后您可以使用

    与列表区分开来
          YourList.Select(x => x.Id).Distinct();
    

    请注意,这将返回完整的记录,而不仅仅是 ID。

    【讨论】:

      【解决方案5】:

      很抱歉为非常旧的线程发布答案。我的回答将来可能会对其他人有所帮助。

      string[] TobeDistinct = {"Name","City","State"};
      DataTable dtDistinct = GetDistinctRecords(DTwithDuplicate, TobeDistinct);
      
          //Following function will return Distinct records for Name, City and State column.
          public static DataTable GetDistinctRecords(DataTable dt, string[] Columns)
             {
                 DataTable dtUniqRecords = new DataTable();
                 dtUniqRecords = dt.DefaultView.ToTable(true, Columns);
                 return dtUniqRecords;
             }
      

      【讨论】:

        【解决方案6】:

        所有功劳归功于 Rajeev Kumar 的回答,但我收到了一个匿名类型的列表,该列表评估为字符串,这并不容易迭代。如下更新代码有助于返回一个更易于操作的 List(或者,例如,直接放入 foreach 块中)。

        var distinctIds = datatable.AsEnumerable().Select(row => row.Field<string>("id")).Distinct().ToList();
        

        【讨论】:

          【解决方案7】:

          注意:Columns[0] 是您要对其执行DISTINCT 查询和排序的列

          DataView view = new DataView(DT_InputDataTable);
          
          DataTable distinctValues = new DataTable();
          
          view = new DataView(DT_InputDataTable) { Sort = DT_InputDataTable.Columns[0].ToString() };
          
          distinctValues = view.ToTable(true, DT_InputDataTable.Columns[0].ToString());
          

          【讨论】:

          • view.ToTable(true, --> 这将获得 DT_InputDataTable.Columns[0].ToString() 的所有不同值
          猜你喜欢
          • 1970-01-01
          • 2013-02-10
          • 1970-01-01
          • 2011-11-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-01-10
          相关资源
          最近更新 更多