使用具有两种不同类型的运算符
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 ( >= 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;
【讨论】:
以上是关于使用具有两种不同类型的运算符的主要内容,如果未能解决你的问题,请参考以下文章