【问题标题】:C#: iterating through DataTable columns of unknown names to check dataC#:遍历未知名称的 DataTable 列以检查数据
【发布时间】:2017-03-13 18:23:00
【问题描述】:

我有一个从 Excel 工作表填充的DataTable,现在需要根据该列中的内容来操作数据。

例如,如果ColumnA 包含数字 1、2 和 3 的组合,则保持该列不变,但如果 ColumnA 没有这种组合,则应删除该列。

现在如果我使用dataTable.Select("") 方法就会出现问题。
我不知道列名以及如何在所有列中实现这一点,并在列中实际应用 where 子句。这种操作都是基于列而不是行。

如果有人有建议或可以指出正确的方向,请做。

编辑 下面是使用 ExcelSheet 填充 DataTable 的代码。

ds = new DataSet();
using (OleDbConnection con = new OleDbConnection(Excel07ConString))
{
    using (OleDbCommand cmd = new OleDbCommand())
    {
        using (OleDbDataAdapter oda = new OleDbDataAdapter())
        {
            cmd.Connection = con;
            con.Open();
            DataTable dtExcelSchema = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);

            for (int i = 0; i < dtExcelSchema.Rows.Count; i++)
            {
                sheetName = dtExcelSchema.Rows[i]["TABLE_NAME"].ToString();
                DataTable dt = new DataTable();
                cmd.Connection = con;
                cmd.CommandText = "SELECT * FROM [" + sheetName + "]";
                oda.SelectCommand = cmd;
                oda.Fill(dt);
                dt.TableName = sheetName;
                comboBoxData.Add(sheetName.Replace("$", ""));
                ds.Tables.Add(dt);
            }
        }
    }
}

【问题讨论】:

  • 是未命名的列,因为它们的名称不是从 Excel 中的标题行传输的,还是您无法从 DataTable.Columns 获取它们?显示您到目前为止编写的代码可能会有所帮助。
  • @dlatikay 列已命名,但最初在填充数据表后,我无法说出列的名称和数量。而且我不想硬编码这些名称,因为 Excel 工作表有不同的名称和格式。所以我们需要盲目地研究它们。我将用代码编辑问题。
  • 同一组规则是否适用于每一列的内容?那么它只是意味着迭代foreach(var column in dataTable.Columns) { ... },并使用循环中的列名动态构建您的查询
  • @dlatikay 是的一组规则适用于所有列。
  • 好的。基本概念很清楚,还有一件事:当您谈论“数字 1、2、3 的组合”时,您会在单元格中寻找它吗?并在以下情况下删除整个列:全部匹配/不匹配/某些匹配?

标签: c# .net winforms datatable


【解决方案1】:

首先,通过将规则应用于每个数据来确定要删除的列:

var columnsToRemove = new List<DataColumn>();

foreach(var column in dataTable.Columns)
{
    if(BusinessRulesSatisfied(dataTable, column) == false)
    {
        columnsToRemove.Add(column);
    }
}

如果需要在BusinessRulesSatisfied 的实际实现中按名称寻址列,您可以使用column.ColumnName 来实现。

然后删除发现不符合规则的列:

foreach(var column in columnsToRemove)
{
    dataTable.Columns.Remove(column);
}

通过这种方式,列名不予考虑。这是推荐的,因为 Excel 没有严格的关系表概念,允许空标题和重复标题。

【讨论】:

  • 这很有意义,我在“BusinessRulesSatisfied”上看到您传递了我可以接受的 DataTable 和列,但现在我将应用的规则让我们回到如何实施查询?我错过了什么吗?我们能否进一步讨论“BusinessRulesSatisfied”...
【解决方案2】:

这是一种在现有 DataTable 上应用附加行过滤规则的相对简单的方法。我不知道需要应用于每一列的实际过滤规则,所以为了简单起见,我假设了一个简单的“每列 1”规则:

string filter = "";
foreach (DataColumn dc in dtExcelSchema.Columns)
{
    if (filter != "")
        filter += " AND ";

    filter += dc.ColumnName + " <> 1";
}

// so at the end, filter will be a string in the form of "ColumnA <> 1 AND ColumnB <> 1 AND ColumnC <> 1" etc
dtExcelSchema.DefaultView.RowFilter = filter;

【讨论】:

    猜你喜欢
    • 2020-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-21
    • 1970-01-01
    • 2012-09-12
    • 1970-01-01
    • 2011-06-07
    相关资源
    最近更新 更多