当我尝试强制转换为(int?)时,指定的强制转换无效

时间:2020-06-18 09:23:51

标签: c# sql-server winforms

我有这段代码可以将数据保存到数据库

for (int i = 0; i < dt.Rows.Count; i++)
        {
            var row = dt.Rows[i];

            await stock.AddProjectNeedsBoltsTest(Convert.ToInt32(row["Quantité"]),
                (int?)row["Filetage"],
                Convert.ToInt32(row["idProject"]),
                (int?)row["idCategory"],
                (int?)row["idType"]).ConfigureAwait(true);
        }

这是AddProjectNeedsBoltsTest背后的代码

public async Task AddProjectNeedsBoltsTest(int Quantity, int? Filetage, int IdProject, int? IdCategory, int? IdType)
    {
        DAL.DataAccessLayer DAL = new DAL.DataAccessLayer();
        await Task.Run(() => DAL.Open()).ConfigureAwait(false);
        SqlParameter[] param = new SqlParameter[5];

        param[0] = new SqlParameter("@Quantity", SqlDbType.Int)
        {
            Value = Quantity
        };

        param[1] = new SqlParameter("@Filetage", SqlDbType.Int)
        {
            Value = Filetage.HasValue ? Filetage : (object)DBNull.Value
        };

        param[2] = new SqlParameter("@IdProject", SqlDbType.Int)
        {
            Value = IdProject
        };

        param[3] = new SqlParameter("@IdCategory", SqlDbType.Int)
        {
            Value = IdCategory.HasValue ? IdCategory : (object)DBNull.Value
        };

        param[4] = new SqlParameter("@IdType", SqlDbType.Int)
        {
            Value = IdType.HasValue ? IdType : (object)DBNull.Value
        };

        await Task.Run(() => DAL.ExcuteCommande("AddProjectNeedsBoltsTest", param)).ConfigureAwait(false);
        DAL.Close();

    }

这是我的存储过程

    CREATE PROCEDURE dbo.AddProjectNeedsBoltsTest
        @Quantity int
       ,@Filetage int
       ,@IdProject int
       ,@IdCategory int
       ,@IdType int
AS
INSERT INTO [dbo].[ProjectNeedsBolts]
       ([Quantity]
       ,[Filetage]
       ,[IdProject]
       ,[IdCategory]
       ,[IdType])
 VALUES
       (@Quantity
       ,@Filetage
       ,@IdProject
       ,@IdCategory
       ,@IdType)

现在,当我单击“保存”按钮时,出现此错误

Smart Industrial Management.exe中发生了类型为'System.InvalidCastException'的异常,但未在用户代码中处理 附加信息:指定的演员表无效。

在此行代码上调试

(int?)row["Filetage"]

我收到此错误消息

无法将'row [“ Filetage”]'拆箱为'int?'

更新:这是我的数据表

DataTable dt = new DataTable();
    void CreateDataTable()
    {
        dt.Columns.Add("Quantité");
        dt.Columns.Add("Filetage");
        dt.Columns.Add("idProject");
        dt.Columns.Add("idCategory");
        dt.Columns.Add("idType");

        gridControl1.DataSource = dt;
    }

如果我尝试

dt.Columns.Add("Filetage", typeof(int?));

我收到错误消息

DataSet不支持System.Nullable <>

1 个答案:

答案 0 :(得分:2)

实际上,DataTable不支持int?-您将其添加为int-DataTable分别处理了空性 。对于演员表,有两种可能性:

  1. 值为DBNull
  2. 该值是其他内容-不是int;也许是longstring

对于1-只需检查值is DBNull,如果是这样:不要尝试将其强制转换为int-自己处理null

对于2-您必须执行自己的解析/转换代码,但坦率地说:最好将数据库修复为正确

但是,坦率地说:我要说的是:像Dapper这样的工具可以使它消失-不DataTable,不用担心。您只需将List<ProjectNeedsBolts>之类的东西用于POCO:

public class ProjectNeedsBolts {
    public int Quantity {get;set;}

    public int IdType {get;set;}
}

(或int?,或您需要的其他任何东西),然后让该库为您完成所有工作:

await conn.ExecuteNonQueryAsync(
    "AddProjectNeedsBoltsTest",
    new { Quantity, Filetage, IdProject, IdCategory, IdType }
    commandType: CommandType.StoredProcedure).ConfigureAwait(false);

或:

var data = await conn.QueryAsync<ProjectNeedsBolts>(
    "your select sql",
    new {...} // parameters
}).ConfigureAwait(false);