使用具有两种不同类型的运算符

Posted

技术标签:

【中文标题】使用具有两种不同类型的运算符【英文标题】: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 是否为空。 【参考方案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;

【讨论】:

以上是关于使用具有两种不同类型的运算符的主要内容,如果未能解决你的问题,请参考以下文章

模板类运算符重载多个类型名 C++

运算优先级及类型转换

c语言 不同数据类型间的混合运算

具有不同比较器的 SQL IN 运算符

==运算符和equals()方法的区别

C/C++编程笔记:C++多态性知识详解