数据行 "Specified Cast is invalid" C#

DataRow "Specified Cast is invalid" C#

无法弄清楚为什么这行不通。我收到相同的“Specified Cast is Invalid”错误消息。 C# 新手,请善待。它在 if(!((int)WrkRow["ManualWeight"] == 1 | 等行失败。我尝试了一些代码变体,没有全部粘贴在这里。ManualWeight 是table.

中的数字字段
              if (dt.Rows.Count > 0)
            {
                DataRow WrkRow = dt.Rows[0];    // ds.Tables(0).Rows(0)
                if (mod1.IsTareout == true)
                    trim = (string)WrkRow["Trucker"];
                sBarcode = $"{trim.Trim()}{(string)WrkRow["TruckNo"]} ";

                XRSwatLaserCert rSwatLaserCert = new XRSwatLaserCert();
                rSwatLaserCert.DataSource = dt;

                DevExpress.XtraReports.UI.ReportPrintTool rpt = new DevExpress.XtraReports.UI.ReportPrintTool(rSwatLaserCert);
                {
                    XRBarCode XrBCTareOut = new XRBarCode();
                    rSwatLaserCert.XrBCTareOut = new XRBarCode
                    {
                        Text = sBarcode
                    };
                    if (!((int)WrkRow["ManualWeight"] == 1 | (int)WrkRow["ManualWeight"] == 3))
                    {
                        rSwatLaserCert.XrLabelManualGross1.Visible = false;
                        rSwatLaserCert.XrLabelManualGross2.Visible = false;
                        rSwatLaserCert.XrLabelManualGross3.Visible = false;
                    }

第二次尝试:

            if (dt.Rows.Count > 0)
            {
                DataRow WrkRow = dt.Rows[0];    // ds.Tables(0).Rows(0)
                if (mod1.IsTareout == true)
                    trim = (string)WrkRow["Trucker"];
                sBarcode = $"{trim.Trim()}{(string)WrkRow["TruckNo"]} ";

                XRSwatLaserCert rSwatLaserCert = new XRSwatLaserCert();
                rSwatLaserCert.DataSource = dt;

                DevExpress.XtraReports.UI.ReportPrintTool rpt = new DevExpress.XtraReports.UI.ReportPrintTool(rSwatLaserCert);
                {
                    XRBarCode XrBCTareOut = new XRBarCode();
                    rSwatLaserCert.XrBCTareOut = new XRBarCode
                    {
                        Text = sBarcode
                    };
                    if (WrkRow.Field<int>("ManualWeight") != 1 | (int)WrkRow.Field<int>("ManualWeight") != 3)
                    {
                        rSwatLaserCert.XrLabelManualGross1.Visible = false;
                        rSwatLaserCert.XrLabelManualGross2.Visible = false;
                        rSwatLaserCert.XrLabelManualGross3.Visible = false;
                    }

第三次尝试:

                if (dt.Rows.Count > 0)
            {
                DataRow WrkRow = dt.Rows[0];    // ds.Tables(0).Rows(0)
                if (mod1.IsTareout == true)
                    trim = (string)WrkRow["Trucker"];
                sBarcode = $"{trim.Trim()}{(string)WrkRow["TruckNo"]} ";

                XRSwatLaserCert rSwatLaserCert = new XRSwatLaserCert();
                rSwatLaserCert.DataSource = dt;

               ReportPrintTool rpt = new ReportPrintTool(rSwatLaserCert);
                {
                    XRBarCode XrBCTareOut = new XRBarCode();
                    rSwatLaserCert.XrBCTareOut = new XRBarCode
                    {
                        Text = sBarcode
                    };
                    var manweight = WrkRow.Field<int>("ManualWeight");
                    if (manweight != 1 | manweight == 3)
                    {
                        rSwatLaserCert.XrLabelManualGross1.Visible = false;
                        rSwatLaserCert.XrLabelManualGross2.Visible = false;
                        rSwatLaserCert.XrLabelManualGross3.Visible = false;
                    }

看看这张图片,里面有很多内容,但希望它有助于理解内容:

快速数据表,带有字符串、整数和小数;约翰今年 20 岁,体重 10.123 随便

当数据表在其行中存储数据时,每一行实际上是一个 object 的数组,这意味着任何时候你得到一个特定列的值,它看起来就像一个 object

看看我在哪里拉 var johnWeight - 我使用 var 让 C# 决定类型,所以我没有误导证人。查看 Locals window(左下角)- 类型是 object{decimal} - 这意味着它是 decimal,但装在 object

要将其输出为 decimal 10.123,我们必须使用 (decimal) 进行投射。这是您在此阶段唯一可以做的事情;您不能使用任何其他类型剥离 object 换行符,甚至不能将小数转换为一个。查看 decimal johnWeightDecimal = (decimal)johnRow["Weight"] 行;那就是剥离 object 包装并获取 decimal 值。可以在localswindow里面看到在type栏

里面是一个decimal

如果你想要它作为一个 int,即使它确实是一个 decimal 并且包裹在 object 中,你首先必须使用转换为 true 来将对象包裹起来键入 (decimal),然后使用 (int) 再次将其 转换为 int。那是 decimal johnWeightInt = (int)(decimal)johnRow["Weight"] 行..


因此,如果您不知道您的物品是什么类型,您可以将其转储到即时 Window(见屏幕截图的右下方),或者您可以导航 Locals window 并展开树,找到 Columns 集合,展开它,找到条目,检查它们的 DataType..

所有这些加起来就是为什么普通 DataTables 使用起来非常痛苦。有一个解决方案:

  • 将 DataSet 类型的文件添加到您的项目
  • 打开它,右键单击,向其中添加一个数据表,向数据表中添加列,设置它们的数据类型
  • 现在您可以像使用任何其他具有命名属性的合理 class 一样使用它:

..none 这个铸造铸造铸造乏味。 dt[0].Weight,不是(decimal)dt.Rows[0]["Weight"]

重要的是,一个 PersonDataTable 仍然是一个 DataTable(它继承自它)所以你可以,例如将其传递给正在执行 SELECT Name, Age, Weight FROM users

的某个数据适配器
var dt = new PersonDataTable();
someDataAdapter.Fill(dt);

DataSet 中实际上有一个完整的生态系统来生成特定类型的 DataAdapter,但这有点超出 post

的范围
  1. 你能检查一下该列值是否为空吗?

  2. 保险起见,能不能转成字符串,用Convert.ToInt32方法?

  3. 你能做一个权重变量,这样你就可以调试并将鼠标悬停在它上面看看它是什么吗?

     if(!WrkRow.IsNull("ManualWeight"))
     {
         var weight = Convert.ToInt32(WrkRow["ManualWeight"].ToString());
    
         if(weight == 1 || weight == 3)
         {
             ....
         }
     }