Проверьте DbNull перед кастомом C # - PullRequest
0 голосов
/ 11 октября 2018

Я пытаюсь запросить базу данных SQL Server и вернуть ответ в формате JSON.Я пытаюсь код ниже

      using (SqlConnection connection = new SqlConnection(connStr))
        {
            SqlCommand command = new SqlCommand(commandText, connection);
            command.Parameters.Add("@ROOM_Data", SqlDbType.VarChar);
            command.Parameters["@ROOM_Data"].Value = ROOM;
            connection.Open();
            List<DatabaseResult> records = new List<DatabaseResult>();

            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    var row = new DatabaseResult
                    {
                        request_id = (int)reader["request_id"],
                        room = (string)reader["room"],
                        jrs_no = (int)reader["jrs_no"],
                        submit_date = (DateTime)reader["submit_date"],
                        sample_no = (int)reader["sample_no"],
                        animal_id = (string)reader["animal_id"],
                        pen_id = (string)reader["pen_id"],
                        ped_no = (string)reader["ped_no"],
                        gender = (string)reader["gender"],
                        dob = (DateTime)reader["dob"],
                        parent_mating = (string)reader["parent_mating"],
                        generation = (string)reader["generation"],
                        allele = (string)reader["allele"],
                        status_type = (string)reader["status_type"],
                        genotype = (string)reader["genotype"],
                        comments = (string)reader["comments"],
                        completion_date = (DateTime)reader["completion_date"],
                        disposition = (string)reader["disposition"],

                    };
                    records.Add(row);
                }
                return Ok(records);

Здесь у меня проблема, когда в любом поле есть ноль.Я пытался заглянуть на другие форумы, могу ли я понять, что нам нужно проверять каждый столбец, является ли он пустым или нет перед кастом.Но я проверяю, могу ли я справиться с методом, который может обрабатывать все случаи?

Ответы [ 6 ]

0 голосов
/ 11 октября 2018

Вы должны быть осторожны при парсинге int вашего кода, потому что он может вернуть вам ошибку.

Почему бы вам не попробовать, прежде чем вы продолжите запускать его в коде и исправить его в своем коде?запрос с использованием isnull.

select isnull(yourNumField,'0')

0 голосов
/ 11 октября 2018

Вы можете проверить значение столбца по DBNull.Value следующим образом:

request_id = (reader["request_id"] == DBNull.Value) ? default(int) : (int)reader["request_id"];

Если вы хотите упростить процесс для всех столбцов, создайте метод расширения, который сравнивается с DBNull.Value, как в этом примере:

// using DBNull.Value comparison
public static T GetValue<T>(this SqlDataReader reader, string columnName)
{
    var value = reader[columnName]; // read column value

    return value == DBNull.Value ? default(T) : (T)value;
}

// alternative using GetOrdinal and IsDBNull
public static T GetValue<T>(this SqlDataReader reader, string columnName) 
{
    int index = reader.GetOrdinal(columnName); // read column index

    return reader.IsDBNull(index) ? default(T) : (T)reader.GetValue(index);
}

Пример использования:

request_id = GetValue<int>(reader, "request_id");
0 голосов
/ 11 октября 2018
request_id = reader["request_id"] == DBNull.Value ? null : (int?)reader["request_id"] ,
room = reader["room"].ToString(),
jrs_no = reader["jrs_no"] == DBNull.Value ? null : (int?)reader["jrs_no"] ,
submit_date = reader["submit_date"] == DBNull.Value ? null : (DateTime?)reader["submit_date"],
sample_no = reader["sample_no"] == DBNull.Value ? null : (int?)reader["sample_no"],
animal_id = reader["animal_id"].ToString(),
pen_id = reader["pen_id"].ToString(),
ped_no = reader["ped_no"].ToString(),
gender = reader["gender"].ToString(),
dob = reader["dob"] == DBNull.Value ? null : (DateTime?)reader["dob"],
parent_mating = reader["parent_mating"].ToString(),
generation = reader["generation"].ToString(),
allele = reader["allele"].ToString(),
status_type = reader["status_type"].ToString(),
genotype = reader["genotype"].ToString(),
comments = reader["comments"].ToString(),
completion_date = reader["completion_date"] == DBNull.Value ? null : (DateTime?)reader["completion_date"],
disposition = reader["disposition"].ToString(),

Нулевое значение базы данных, которым вы можете управлять, как вам нравится.переменные int и datetime изменяются на int?а дата и время?соответственно, или вы можете установить значение по умолчанию в случае, если значение в БД пустое

0 голосов
/ 11 октября 2018

Попробуйте вот так

public static class SqlReaderExtention {

     public static T GetValue<T>(this SqlDataReader reader, string fieldName) {
        int columnIndex = reader.GetOrdinal(fieldName);
        if (reader.IsDBNull(columnIndex)) {
           return default(T);
        }

        return (T)reader.GetValue(columnIndex);
     }
 }
0 голосов
/ 11 октября 2018

если вам нужно использовать datareader и вы определяете свой собственный raw sql, что, как представляется, имеет место, то в sql вы можете обернуть модифицированную инструкцию sql для использования проверок ISNULL в части выбора.напр. - убедитесь, что возвращается строковый столбец и пустая строка ('') вместо NULL

select isnull(foo,'') from myTable
0 голосов
/ 11 октября 2018

Одна проблема заключается в том, что int не обрабатывает нулевые значения при его приведении.

Попробуйте

sample_no = (int?)reader["sample_no"]

и в вашем классе DatabaseResult

объявить sample_no как int? sample_no

int? означает его обнуляемое значение int, где, если вы передадите ему нулевые значения, оно не сгенерирует исключение.

другоеМетод будет int.TryParse, где вместо него будет 0, если обнаружится, что это нулевое значение.

...