【问题标题】:Using Operators with two different Types使用具有两种不同类型的运算符
【发布时间】:2020-02-09 08:48:26
【问题描述】:

我有一个已经创建的 DataView。我从现有的 DataView 构建了一个新的 DataTable,并将该数据作为 DataView 导出到 XlSX。我正在尝试检查最后一列是否具有大于 0 的整数。如果是,则应删除该行。由于这是两种不同的类型,一种是对象,另一种是双精度类型,所以并没有我想象的那么简单。

我已经在Operator '<' cannot be applied to operands of type 'object' and 'int'上查看了答案

在大多数情况下,这会完成,但是在某处它会返回一个 DBNull.Value,如所述。如果我尝试解析它似乎不喜欢它并且它不会构建。

private DataView CreateExhaustionDataView()
{
    DataTable dt = BuildFufillmentDataTable();
    DataView dv = new DataView(dt, "", "Department,Date", DataViewRowState.CurrentRows);

    DataTable result = dv.ToTable(true,"Department","Date","Remaining");
    var dr = result.NewRow();
    if (Convert.ToDouble(dr["Remaining"]) >= 0.0)
    {
        dr.Delete();
    }
    DataView dvresult = new DataView(result);
    return dvresult;
}

我在尝试转换时收到此错误消息:

System.InvalidCastException: '对象不能从 DBNull 转换为其他类型。' 我只在导出数据时收到此错误。 就解析而言,它根本没有构建。

如果我错过了任何提示或路线,我将不胜感激!

【问题讨论】:

  • 1) 这不会编译:if ( &gt;= 0.0)。请提供将编译的代码。 2) 究竟是在哪一行抛出异常?
  • 我更新了代码,它只在 If 语句行出错。
  • 在将dr["Remaining"] 传递给Convert.ToDouble() 之前,首先检查是否dr["Remaining"] == DBNull.Value。如果它等于 DBNull.Value,它是 null,你会得到这个异常。您不会从空值的数据库列中获得常规的null,只是那个特殊的常量。
  • 嘿,等一下,您正在创建一个充满空值的新行并查看它。当然是空的。您想要结果中的第一行:var firstrow = result.Rows.FirstOrDefault(),并检查 firstrow 是否为空。

标签: c# datatables dataview


【解决方案1】:

事实证明,本质上,OP 想要to filter result

您不是在查看第一行,而是在创建一个与 DataTable 具有相同列的新行,然后查看它。在您明确添加之前,该新行甚至不会出现在 DataTable 中。

var dr = result.NewRow();

dr 中的值都是空的,因为你刚刚创建了可怜的东西。您也没有检查该列是否为空,您应该这样做。

if (result.Rows.Count > 0)
{
    var firstrow = result.Rows[0];

    if (firstrow["Remaining"] != DBNull.Value 
        && Convert.ToDouble(firstrow["Remaining"]) >= 0.0)
    {
        //  Or maybe firstrow.Delete(), I don't have time to test this. 
        //  If one doesn't work, try the other. 
        result.Rows.Remove(firstrow);
    }
}

【讨论】:

  • 如果该行的整数大于 0,则这两种方法都不会删除该行,但这至少会使其不会引发异常并将我指向正确的方向。谢谢!
  • 好的 找出它是什么。这实际上只执行第一行。如果我想让它通过并对所有行执行此操作,是否必须将其放入 for 循环中?
  • @AverageJoe 是的,你需要一个循环。我想我误读了您的代码的意图。另外,您是要从结果对象中删除,还是从实际的数据库表中删除?
  • 基本上我只是想让 XLSX 文件在 ["Remaining"] 列中仅包含负数。它可以保留在表格中,并将其从结果中删除就可以了。将其从整个数据库表中删除会更有效吗?
  • 我希望从结果中删除它会更简单。我想你也可以在上面设置一个过滤器——甚至更简单。
【解决方案2】:

我找到了一种无需使用前面讨论的 For 循环即可简单地对数据表进行排序的方法。我评论了 For 循环来测试排序,实际上在没有那么多代码行的情况下也能正常工作。

private DataView CreateExhaustionDataView()
{
    DataTable dt = BuildFufillmentDataTable();
    DataView dv = new DataView(dt, "", "Department,Date", DataViewRowState.CurrentRows);
    DataTable result = dv.ToTable(true, "Department", "Date", "Remaining");
    /*for (int i= result.Rows.Count-1; i >= 0; i--)
    {
        if (result.Rows.Count > 0)
        {
            var firstrow = result.Rows[i];

            if (firstrow["Remaining"] != DBNull.Value
                && Convert.ToDouble(firstrow["Remaining"]) > 0.0)
            {
                firstrow.Delete();
            }
        }
    }*/ 
    DataView dvresult = new DataView(result, "Remaining <= 0", "Department, Date", DataViewRowState.CurrentRows);
    return dvresult;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 2016-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多