【问题标题】:Compare one datatable's rows to another datatable's columns将一个数据表的行与另一个数据表的列进行比较
【发布时间】:2013-06-21 20:10:27
【问题描述】:
first table:dtHeader
 Header
---------
Address
ZipCode
city
state


Second table:-dtReport

RowNumber-----Address------Zipcode---Region------city

   1200       JC           00000     NYC         Bronx

   13000       RC            12345    NC          Boston

我想删除 dtreport 中列名不在 dtHeader 中的所有列 所以结果 dtReport 将只有 Address--zipcode--city 列。 我不想创建另一个数据表,因为它有大量行,即 70000 我怎样才能做到这一点?

【问题讨论】:

  • 你是否已经写了一些东西,或者你完全坚持这个?
  • 我完全坚持这一点。它要么删除所有列,要么删除所需的列但不删除不需要的列。

标签: c# datatable


【解决方案1】:

您可以使用Enumerable.Except 查找必须从dtReport 中删除的所有列名

var notAllowedColNames = dtReport.Columns.Cast<DataColumn>()
    .Select(c=> c.ColumnName.ToUpperInvariant())
    .Except(dtHeader.AsEnumerable().Select(r => r.Field<String>("Header").ToUpperInvariant()))
    .ToList();
foreach(var colName in notAllowedColNames) 
     dtReport.Columns.Remove(colName);

我使用了ToUpperInvariant,因为ZipCode 在两个表中都有不同的大小写。

【讨论】:

  • 这个工作就像魅力......它真的很神奇......我很长时间以来一直坚持这个!非常感谢。
【解决方案2】:

未测试,但 dtReport 列集合上的一个简单循环检查 dtHeader 列集合是否包含同名列。如果不从 dtReport 中删除该列。

    SqlCommand cmdHeader = new SqlCommand("SELECT * FROM Header", conn);
    SqlCommand cmdReport = new SqlCommand("SELECT * FROM Report", conn);
    DataTable dtHeader = new DataTable();
    DataTable dtReport = new DataTable();
    SqlDataAdapter da1 = new SqlDataAdapter(cmdHeader);
    da1.Fill(dtHeader)
    SqlDataAdapter da2 = new SqlDataAdapter(cmdReport);
    da2.Fill(dtReport);

    for(int x = dtReport.Columns.Count - 1; x >= 0; x--)
    {
        DataColumn dc = dtReport.Columns[x];
        if(!dtHeader.Columns.Contains(dc.ColumnName))
             dtReport.Columns.Remove(dc.ColumnName);
    }

诀窍是使用从最后一列到第一列的 for..loop。通过这种方式,您可以在遍历集合时删除列(foreach 不能这样做)

【讨论】:

  • 谢谢。我用于每个循环,这就是我被卡住的地方。我会试试这个。头表是c#生成的,而不是从数据库生成的,而报告表是从数据库生成的!
  • 嘿,我尝试了您的解决方案,但它并没有像我想要的那样工作。但是非常感谢你帮助我。很长一段时间以来,我真的一直坚持这一点。谢谢。
  • @Steve:为什么认为涉及数据库?
  • @TimSchmelter 可能这是我的一种心理习惯,当我看到一个以 dt 开头的变量时,我想到了一个 DataTable
  • @Steve:是的,当然有DataTables,正如 OP 在 qustion 中提到的那样。但是DataTable 只是内存中的数据集合,它们可以从任何地方填充,不需要数据库。实际上 OP 询问如何从现有和填充的表中删除列,这就是为什么我看到两个 sql 答案有点惊讶。
【解决方案3】:

一个全 SQL 的答案应该是这样的

    INSERT INTO #TEMP_TABLE
  SELECT c.name
FROM sys.tables AS t
INNER JOIN sys.columns AS c ON t.OBJECT_ID = c.OBJECT_ID
WHERE t.name = 'dtReport' AND c.name NOT IN (SELECT Header FROM dtHeader)

  WHILE ((SELECT COUNT(*) FROM #TEMP_TABLE) > 0)
    BEGIN
        DECLARE @COLUMN_NAME VARCHAR(50) = (SELECT TOP 1 Header FROM #TEMP_TABLE)
        ALTER TABLE PATRON DROP COLUMN @COLUMN_NAME
        DELETE FROM #TEMP_TABLE WHERE Header = @COLUMN_NAME
    END

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-14
    • 2023-03-09
    • 2017-07-07
    • 2021-05-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多