Rambler's Top100
Главная
Новости
Статьи
Форумы
Книги
Коды
Сообщество
Блоги
О нас
 

Логин

Email:
  Пароль:

Войти
Зарегистрироваться
Забыл пароль

Поиск

 Искать :
 
Вперед

Активные блоггеры

 Игорь Т. (7)
 clevelus (1)
 sniffer (1)
 Devel (1)
 GreenAsh (2)
 Валерия  (2)
 avot (1)
 thejediknight (1)
 Vladimir (1)
 advanta-group (1)
 Sheba (2)
 dmitry39 (4)
 Ivinsky (1)
 gvd (1)
 OlegNV (1)
 Naxelar (1)
 devnetwork (1)
 StroyFasad (1)
 Nikolai333 (1)
 Tatjana (1)

 | 

C...R...a...S...H Blog.

Sunday, July 16, 2006

Борьба с null в .NET Framework 2.0

Часто при работе с базами данных возникает такая проблема: как хранить данные из полей, которые могут содержать значения NULL, ведь простые типы данных в .NET не могут иметь значение NULL.
Существует большое количество способов сделать это возможным, .NET Framework 2.0 предлагает нам свой способ, основанный на классе Nullable и соответствующей структуры с таким же названием.


Вот список основных свойств и методов данной структуры:


GetValueOrDefault
GetValueOrDefault(T)

Если значение NULL, то данный метод возвращает значение типа по умолчанию или значение, переданное ему в качестве параметра, если же нет, то возвращается значение свойства Value
HasValue
Возвращает True, если переменная не NULL, и False в противном случае
Value
Возвращает значение переменной, если оно NULL, то генерируется исключение InvalidOperationException.


Класс Nullable содержит следующие методы:


Equals (Generic Nullable, Generic Nullable)
Перегруженный метод, который проверяет эквивалентность двух Nullable объектов
Compare
Метод сравнивает два значения Nullable объекта
GetUnderlyingType
Возвращает тип лежащий в основе Nullable.


Немного подробнее о методе Compare.


Данный метод имеет 2 параметра Nullable<T>. Возвращает Integer значение – результат сравнения.
Меньше нуля
Первый параметр – NULL, а второй не NULL или
Значение первого параметра меньше значения второго параметра
Ноль
Оба параметра NULL или
Значения двух параметров совпадают
Больше нуля
Первый параметр не NULL, а второй – NULL или
Значение первого параметра больше значения второго параметра.


Практическое использование класса и структуры Nullable


C#

using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
namespace TestNullable
{
    class Program
    {
        /// <summary>
        /// Объявляем структуру для хранения записей из таблицы
        /// </summary>
        public struct TestNull
        {    //Конструктор структуры, который позволяет заполнить все ее поля
            public TestNull(int _Id, string _Name, DateTime _DateBegin, DateTime? _DateEnd)
            {
                id = _Id;
                Name = _Name;
                DateBegin = _DateBegin;
                DateEnd = _DateEnd;
            }
            //Объявление полей структуры
            public int id;
            public string Name;
            public DateTime DateBegin;
            public DateTime? DateEnd; //Объявление Nullable DateTime, так же правильным может считаться объявление public Nullable<DateTime> DateEnd
        }
        static void Main(string[] args)
        {
            //Создаем Generic список, который будет содержать записи из таблицы
            List<TestNull> Table = new List<TestNull>();
            //Подключаемся к базе данных, что бы загрузить данные из таблицы
            using (SqlConnection con = new SqlConnection(@"Data Source= nick2005;Initial Catalog=Test;Integrated Security=True"))
            {
                con.Open();//Открываем соединение
                SqlCommand cmd = con.CreateCommand(); //Создаем объект SQL-команды
                cmd.CommandText = "select * from users"; //Вносим запрос, который хотим выполнить
                SqlDataReader reader = cmd.ExecuteReader(); //Создаем объект для чтения результатов запроса

                while (reader.Read()) //Читаем результат
                {
                    //Добавляем записи в наш список
                    Table.Add(new TestNull(reader.GetInt32(0), reader.GetString(1), reader.GetDateTime(2), reader.IsDBNull(3) ? null : (Nullable<DateTime>)reader.GetValue(3)));
                }
                con.Close(); //Закрываем соединение
            }
            //Цикл вывода данных на экран
            foreach (TestNull item in Table)
            {
                Console.WriteLine("ID={0},Name={1},DateBegin={2},DateEnd={3}", item.id, item.Name, item.DateBegin, item.DateEnd.HasValue == false ? "NULL" : item.DateEnd.Value.ToString());
            }
            Console.ReadKey();
        }
    }
}
VB.NET
Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Data.SqlClient
Namespace TestNullable
    Class program
        '''<summary>
        ''' Объявляем структуру для хранения записей из таблицы
        ''' </summary>
        Public Structure TestNull
            'Конструктор структуры, который позволяет заполнить все ее поля
            Public Sub New(ByVal _Id As Integer, ByVal _Name As String, ByVal _DateBegin As DateTime, ByVal _DateEnd As Nullable(Of DateTime))
                Me.id = _Id
                Me.Name = _Name
                Me.DateBegin = _DateBegin
                Me.DateEnd = _DateEnd
            End Sub
            'Объявление полей структуры
            Public DateBegin As DateTime
            Public DateEnd As Nullable(Of DateTime) 'Объявление Nullable DateTime
            Public id As Integer
            Public Name As String
        End Structure
        Shared Sub Main()
            Dim Table As New List(Of TestNull) 'Создаем Generic список, который будет содержать записи из таблицы
            'Подключаемся к базе данных что бы загрузить данные из таблицы
            Using con As SqlConnection = New SqlConnection("Data Source= nick2005;Initial Catalog=Test;Integrated Security=True")
                con.Open() 'Открываем соединение
                Dim cmd As SqlCommand = con.CreateCommand 'Создаем объект SQL-команды
                cmd.CommandText = "select * from users" 'Вносим запрос, который хотим выполнить
                Dim reader As SqlDataReader = cmd.ExecuteReader 'Создаем объект для чтения результатов запроса
                Do While reader.Read 'Читаем результат
                    'Добавляем записи в наш список
                    Table.Add(New TestNull(reader.GetInt32(0), reader.GetString(1), reader.GetDateTime(2), GetValue(reader(3))))
                Loop
                con.Close() 'Закрываем соединение
            End Using
            'Цикл вывода данных на экран
            For Each Item As TestNull In Table
                Console.WriteLine("ID={0},Name={1},DateBegin={2},DateEnd={3}", Item.id, Item.Name, Item.DateBegin, GetValue(Item.DateEnd))
            Next
            Console.ReadKey()
        End Sub
        ''' <summary>
        ''' Функция для проверки значение на DBNull
        ''' </summary>
        ''' <remarks>Данная функция создана из-за того, что IIF в VB.NET вычисляет все значения ей передаваемые, в отличие от С-ой ?:</remarks>
        Private Shared Function GetValue(ByRef obj As Object) As Nullable(Of DateTime)
            If IsDBNull(obj) Then
                Return Nothing
            Else
                Return CType(obj, Nullable(Of DateTime))
            End If
        End Function
        ''' <summary>
        ''' Так же из-за корявой работы функции IIF приходится делать отдельную функцию обработки значения.
        ''' </summary>
        Private Shared Function GetValue(ByRef obj As Nullable(Of DateTime)) As String
            If obj.HasValue Then
                Return obj.Value.ToString
            Else
                Return "NULL"
            End If
        End Function
    End Class
End Namespace
Что бы полнее рассмотреть вопрос работы со структурой Nullable, мне хотелось бы рассмотреть еще несколько примеров: Использование GetValueOrDefault: C#
int? i=null;//Определяем переменную i как Nullable<int> со значение NULL
Console.WriteLine(i ?? 444); //Результат 444
Console.WriteLine(i.GetValueOrDefault()); //Результат 0 - значение int по умолчанию
i = 44; //Записываем значение 
Console.WriteLine(i.GetValueOrDefault(3)); //Результат 44
Console.WriteLine(i); //Результат 44
VB.NET
Dim i As Nullable(Of Integer) = Nothing 'Определяем переменную i как Nullable(Of Integer) со значение Nothing
Console.WriteLine(i.GetValueOrDefault(444)) 'Результат 444
Console.WriteLine(i.GetValueOrDefault) 'Результат 0 - значение int по умолчанию
i = 44 'Записываем значение 
Console.WriteLine(i.GetValueOrDefault(3)) 'Результат 44
Console.WriteLine(i) 'Результат 44
Использование Compare: C#
int? a = null;//Определяем переменную a как Nullable<int> со значение NULL
int? b = null;//Определяем переменную b как Nullable<int> со значение NULL
Console.WriteLine(Nullable.Compare(a, b)); //Результат 0
a = 1;b = null;
Console.WriteLine(Nullable.Compare(a, b)); //Результат 1
a = null;b = 1;
Console.WriteLine(Nullable.Compare(a, b)); //Результат -1
a = 0;b = 1;
Console.WriteLine(Nullable.Compare(a, b)); //Результат -1
a = 1;b = 0;
Console.WriteLine(Nullable.Compare(a, b)); //Результат 1
VB.NET
Dim a As Nullable(Of Integer) = Nothing 'Определяем переменную a как Nullable<int> со значение Nothing
Dim b As Nullable(Of Integer) = Nothing 'Определяем переменную b как Nullable<int> со значение Nothing
Console.WriteLine(Nullable.Compare(a, b)) 'Результат 0
a = 1 : b = Nothing
Console.WriteLine(Nullable.Compare(a, b)) 'Результат 1
a = Nothing : b = 1
Console.WriteLine(Nullable.Compare(a, b)) 'Результат -1
a = 0 : b = 1
Console.WriteLine(Nullable.Compare(a, b)) 'Результат -1
a = 1 : b = 0
Console.WriteLine(Nullable.Compare(a, b)) 'Результат 1




P.S.


Изучив основы использования класса и структуры Nullable, видно, что данную технологию широко можно использовать в языке C#, ведь даже компилятор C# позволяет использовать сокращенный синтаксис:
int?, в место Nullable<int>
item ?? 1, в место item.GetValueOrDefault(1)
А вот ее использование в языке Visual Basic .NET затруднительно, так как придется использовать полное обращение к структуре Nullable(of Integer), а так же основную проблемы вызывает функция IIF, которая, как и в VB6 с начала выполняет все операции, которые ей передали, а только лишь затем выполняет проверку.


C...R...a...S...H

16 July 2006 22:03  Комментарии (1)

Monday, November 28, 2005

Выбор элемента GridView щелчком на него

Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
e.Row.Attributes.Add("onclick", "javascript:__doPostBack('" & e.Row.Cells(e.Row.Cells.Count - 1).Controls(0).UniqueID & "','')")
End If
End Sub
'Последная commandcolumn(скрытая), где содержится кнопка для выполнения выделения.
<asp:ButtonField CommandName="Select" Text="Выбрать" />

C...R...a...S...H

28 November 2005 11:05  Комментарии (1)

Выбор элемента GridView щелчком на него

Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
e.Row.Attributes.Add("onclick", "javascript:__doPostBack('" & e.Row.Cells(e.Row.Cells.Count - 1).Controls(0).UniqueID & "','')")
End If
End Sub
'Последная commandcolumn(скрытая), где содержится кнопка для выполнения выделения.

C...R...a...S...H

28 November 2005 11:01  Комментарии (0)

 
Наш Киев

Apartments for Rent

Rambler's Top100
Рейтинг@Mail.ru
Идея: Dimon aka Manowar Программирование: Dimon aka Manowar Дизайн: Dan Lebedev
Хостинг от компании Parking.ru
Карта сайта