Указанное приведение неверно, когда я пытаюсь выполнить приведение к (int?) - PullRequest
1 голос
/ 18 июня 2020

У меня есть этот код для сохранения данных в базе данных

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)

Теперь, когда я нажимаю кнопку сохранения, я получаю эту ошибку

Исключение типа 'System.InvalidCastException' произошло в Smart Industrial Management.exe, но не было обработано в пользовательском коде Дополнительная информация: Указанное приведение недействителен.

При отладке в этой строке кода

(int?)row["Filetage"]

Я получаю это сообщение об ошибке

Невозможно распаковать строку ["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 Ответ

2 голосов
/ 18 июня 2020

В самом деле, DataTable не поддерживает int? - вы бы добавили его как int - с DataTable с возможностью передачи значения NULL отдельно . Для приведения есть две возможности:

  1. значение DBNull
  2. значение другое - не int; возможно, long или string

Для 1 - просто проверьте, имеет ли значение is DBNull, и если да: не пытайтесь преобразовать его в int - обработайте null

Для 2 - вам нужно будет сделать свой собственный код синтаксического анализа / преобразования, но, честно говоря: было бы лучше исправить базу данных, чтобы она была правильной

Однако, честно говоря: я собираюсь сказать: такие инструменты, как Dapper, позволяют избавиться от этого на go - нет 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...