【问题标题】:Create DataTable using LINQ to select multiple columns使用 LINQ 创建 DataTable 以选择多个列
【发布时间】:2019-06-06 14:02:52
【问题描述】:

我需要从我拥有但只有一些列(完全相同的行)的另一个 DataTable 创建一个 DataTable。

有没有使用 LINQ 的简单方法?

我试过了:

DataTable dataCopy = dt.AsEnumerable()
                       .Select(r => new { A = r.Field<string>("Column A"),
                                          B = r.Field<string>("Column B") });

但它没有“CopyToDataTable”方法。

我正在寻找性能最佳的方法来做到这一点,因为我的“源”数据表非常庞大!

【问题讨论】:

    标签: c# linq datatable


    【解决方案1】:

    您可以简单地使用dataTable.Copy() 复制数据表并从复制的对象中删除不需要的列。

    var dt1 = dt.Copy();
    dt.Columns.Remove("<columnsToRemove>")
    

    【讨论】:

    • 这对性能有好处吗?我的意思是,我的源 DataTable 真的很大,我认为有另一种方法而不是创建它的副本。
    • copy() 方法是 Microsoft 的 API,假设他们对其性能进行了基准测试。就内存而言,如果您在内存中加载了一个数据表,则创建副本会使它翻倍。因此,不要将第一个 dataTable 加载到内存中,而是创建一个 datareader 并直接从中创建第二个表。
    【解决方案2】:
        Stopwatch time = new Stopwatch();
    
                    time.Start();
        //COMPARE YOUR CODE (.Copy, Clone or Develop yourself)
                    DataTable dtTarget = dtSource.CopyDataTable(new List<string>() { "A", "B" });
    
                    foreach (DataColumn column in dtTarget.Columns)
                    {
                        Console.WriteLine("ColumnName : {0}", column.ColumnName);
    
                        foreach (DataRow row in dtTarget.Rows)
                        {
                            Console.WriteLine("Rows : {0}", row[column.ColumnName]);
                        }
                    }
    
                    time.Stop();
    
                    Console.WriteLine("{0}", time.Elapsed);
    
    
    
    public static class DataTableHelper
        {
            public static DataTable CopyDataTable(
               this DataTable dtSource,
                List<string> columnsName)
            {
    
                DataTable dtTarget = new DataTable();
                if (dtSource.Columns.Count > 0)
                {
    
                    foreach (DataColumn columnSource in dtSource.Columns)
                    {
                        var columnTargetMapped = columnsName.FirstOrDefault(c => c == columnSource.ColumnName);
    
                        if(columnTargetMapped == null)
                        {
                            continue;
                        }
    
                        dtTarget.Columns.Add(columnTargetMapped);
    
                        foreach (DataRow drSource in dtSource.Rows)
                        {
                            var valueColumn = drSource[columnSource];
    
                            DataRow drTarget = dtTarget.NewRow();
    
                            drTarget[columnTargetMapped] = valueColumn;
    
                            dtTarget.Rows.Add(drTarget);
                        }
                    }
                }
    
                return dtTarget;
            }
    

    【讨论】:

      【解决方案3】:
          public static DataTable GetDataTablePart(this DataTable dt, params string[] ColumnNames)
          {
              var dtPart = new DataTable("TablePart");
              var Names = new List<DataColumn>();
              foreach (DataColumn Column in dt.Columns)
              {
                  if(ColumnNames.Contains(Column.ColumnName))
                  {
                      Names.Add(Column);
                  }
              }
              dtPart.Columns.AddRange(Names.ToArray());
              foreach(DataRow row in dt.Rows)
              {
                  var NewRow = new object[Names.Count()];
                  var i = 0;
                  foreach (var Name in Names)
                  {
                      NewRow[i] = row[Name];
                      i = i + 1;
                  }
                  dtPart.LoadDataRow(NewRow, false);
              }
              return dtPart;
          }
      

      linq 版本....

          public static DataTable GetDataTablePart(this DataTable dt, params string[] ColumnNames)
          {
              var RowCount = 0;
              var dtPart = new DataTable("TablePart");
              dtPart.Columns.AddRange((from column in dt.Columns.Cast<DataColumn>()
                           where ColumnNames.Contains(column.ColumnName)
                           select column).ToArray());
              return (from row in dt.AsEnumerable()
                        let rowCount = RowCount = dt.Rows.Count
                        let RowValues = (from column in dtPart.Columns.Cast<DataColumn>()
                                         select row[column]).ToArray()
                        let decCount = RowCount = RowCount - 1
                        where dtPart.LoadDataRow(RowValues,LoadOption.OverwriteChanges) != default && decCount > 0
                        select dtPart).FirstOrDefault();
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-09-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多