How to shoot yourself in the foot with nullable types and SQL types *

Labvakar!

Šovakar vēlos jums pastāstīt par kādu lietu, kuru, iespējams, daži jau uzskata par novecojušu. Tomēr ne visi jau ir pārgājuši uz .NET platformas jaunākajām versijām, kā arī jebkurā laikā katram no mums var sanākt uzturēt legacy kodu. Tāpēc pastāstīšu par kādu .NET SQL datu tipu īpatnību, ar kuru ne pārāk sen saskāros.

Lai iepazīstinātu ar problēmu, varētu sarīkot nelielu konkursu, pajautājot, kāds rezultāts būs šādam kodam, gadījumā, ja no datubāzes atgriezīs NULL vērtību (atbilde jāsniedz, nepārbaudot ar programmu):

String output = SomeMethodThatReturnsDbResultWhichIsNull() ?? "Datubāzē nav datu";
Console.WriteLine(output);

Pirmajā brīdī liekas, ka ar kodu viss ir kārtībā, atgrieztais rezultāts tiek pārbaudīts un rezultāts būs "Datubāzē nav ieraksta", tomēr praksē izrādās savādāk un izpildot šādu kodu iegūst SqlNullValueException. Izrādās, ka gadījumos, kad no datubāzes var tikt atgriezta NULL vērtība, ir jāpārbauda īpašība IsNull, kura tad arī norāda, vai mainīgais satur kādu vērtību. No vienas puses vienkārši, no otras - ir redzēti gadījumi, kad izstrādātāji uz šo ir "iekrituši".

Tiem, kam mans apraksts liekas nesaprotams - lai runā kods:

using System;
using System.Data.SqlTypes;

namespace NullableDemo
{
    class Example
    {
        private SqlGuid _guid = new SqlGuid();

        /// <summary>
        /// Gets the property wrong.
        /// </summary>
        /// <value>Exception :)</value>
        public Guid? PropertyWrong
        {
            get { return _guid.Value; }
        }

        /// <summary>
        /// Gets the property right.
        /// </summary>
        /// <value>null</value>
        public Guid? PropertyRight
        {
            get
            {
                if (_guid.IsNull)
                    return null;

                return _guid.Value;
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Example example = new Example();
            try
            {
                Console.WriteLine("Right way:");
                Guid guid = example.PropertyRight ?? Guid.Empty;
                Console.WriteLine(guid);

                Console.WriteLine("Wrong way:");
                guid = example.PropertyWrong ?? Guid.Empty;
                Console.WriteLine(guid);
            }
            catch (SqlNullValueException e)
            {
                Console.WriteLine("Exception:");
                Console.WriteLine(e.Message);
            }
        }
    }
}

Un ekrānšāviņš:

Nullable_demo_output


*How to shoot yourself in the foot links:

Published 13 December 2007 10:03 PM by ivars.arins
Filed under: , ,

Leave a Comment

(obligāts) 
(obligāts) 
(brīvizvēles)
(obligāts)