dnn中NULL值的处理

空处理

每一个数据存取系统都有一个特殊的构造来处理那些没有明确指定的字段值。在大多数关系数据库管理系统中,这个构造就是众所周知的null值。

从应用程序的角度看,在表述层和数据存取层传递null值是一个架构上的挑战。这是因为表述层必须从数据库的特定信息抽象出来;而且,当一个属性值没有明确指定的时候表述层也必须能够表达说明。

事实上这相当复杂,.NET Framework的本身的数据类型不能自动的转换从数据库返回的null值(如果你试图直接那样赋值的话将会抛出一个异常)。另外,每一个数据存储都有它自己的属性来实现null

唯一合理的解决方案就是创建一个抽象的传输服务,来编码/解码应用程序各层之间的null

 

乍一看,你也许会想到用vb.net中的“nothing”关键字可以很好的担负起这个传输服务的任务。不幸的是,调查显示,.NET Framework本身的数据类型处理“nothing”的时候没有预想的那么好。尽管分配为nothing的属性不会抛出异常,实际上这个属性的值将非常依赖于它的数据类型(String = Nothing, Date = Date.MinValue, Integer = 0, Boolean = False, 等等)并且自带的IsNothing()函数的结果还不是一致的(兼容的)结果。

 

DNN里,我们创建了一个通用的类来处理null的问题,它统一管理应用程序各层的null问题。在应用程序中用一个常量来描述每种数据类型的null情况,再把这个常量转化成各种数据存储实现里的实际的null值。这个类包含的各种方法将null转换服务的物理细节从应用程序中抽象出来了。

* 记住,这个类仅仅用在数据库字段允许有null值的情况下。还要记住,这个类要求DALBLL层之间的数据类型一致(例如:一个BLL信息类里的属性字段的数据类型必须跟DAL 数据提供者传递过来的参数的数据类型一致)。

 

 

    Public Class Null

 

        ' define application encoded null values

        Public Shared ReadOnly Property NullInteger() As Integer

            Get

                Return -1

            End Get

        End Property

        Public Shared ReadOnly Property NullDate() As Date

            Get

                Return Date.MinValue

            End Get

        End Property

        Public Shared ReadOnly Property NullString() As String

            Get

                Return ""

            End Get

        End Property

        Public Shared ReadOnly Property NullBoolean() As Boolean

            Get

                Return False

            End Get

        End Property

 

        ' sets a field to an application encoded null value ( used in Presentation layer )

        Public Shared Function SetNull(ByVal objField As Object) As Object

            If TypeOf objField Is Integer Then

                SetNull = NullInteger

            ElseIf TypeOf objField Is Date Then

                SetNull = NullDate

            ElseIf TypeOf objField Is String Then

                SetNull = NullString

            ElseIf TypeOf objField Is Boolean Then

                SetNull = NullBoolean

            Else

                Throw New NullReferenceException()

            End If

        End Function

 

        ' sets a field to an application encoded null value ( used in BLL layer )

        Public Shared Function SetNull(ByVal objPropertyInfo As PropertyInfo) As Object

            Select Case objPropertyInfo.PropertyType.ToString

                Case "System.Int16", "System.Int32", "System.Int64", "System.Single", "System.Double", "System.Decimal"

                    SetNull = NullInteger

                Case "System.DateTime"

                    SetNull = NullDate

                Case "System.String", "System.Char"

                    SetNull = NullString

                Case "System.Boolean"

                    SetNull = NullBoolean

                Case Else

                    Throw New NullReferenceException()

            End Select

        End Function

 

        ' convert an application encoded null value to a database null value ( used in DAL )

        Public Shared Function GetNull(ByVal objField As Object, ByVal objDBNull As Object) As Object

            GetNull = objField

            If TypeOf objField Is Integer Then

                If objField = NullInteger Then

                    GetNull = objDBNull

                End If

            ElseIf TypeOf objField Is Date Then

                If objField = NullDate Then

                    GetNull = objDBNull

                End If

            ElseIf TypeOf objField Is String Then

                If objField = NullString Then

                    GetNull = objDBNull

                End If

            ElseIf TypeOf objField Is Boolean Then

                If objField = NullBoolean Then

                    GetNull = objDBNull

                End If

            Else

                Throw New NullReferenceException()

            End If

        End Function

 

        ' checks if a field contains an application encoded null value

        Public Shared Function IsNull(ByVal objField As Object) As Boolean

            If objField = SetNull(objField) Then

                IsNull = True

            Else

                IsNull = False

            End If

        End Function

 

    End Class

项目实际使用DA层

SqlDataProvider (具体实现类)

 

在具体类中包含了下面的帮助方法,这个方法用来独立数据库null的实现(这个例子中DBNull.Value 是针对SQL Server而言的)并且提供一个简单的接口。

 

 

    ' general

    Private Function GetNull(ByVal Field As Object) As Object

        Return Null.GetNull(Field, DBNull.Value)

    End Function

 

每一个在基类里表明必须继承的方法在具体类里都必须实现。注意上面的add/update方法里描述的GetNull()函数的使用。

 

    ' announcements module

    Public Overrides Function GetAnnouncements(ByVal ModuleId As Integer) As IDataReader

        Return CType(SqlHelper.ExecuteReader(ConnectionString, DatabaseOwner & ObjectQualifier & "GetAnnouncements", ModuleId), IDataReader)

    End Function

    Public Overrides Function GetAnnouncement(ByVal ItemId As Integer, ByVal ModuleId As Integer) As IDataReader

        Return CType(SqlHelper.ExecuteReader(ConnectionString, DatabaseOwner & ObjectQualifier & "GetAnnouncement", ItemId, ModuleId), IDataReader)

    End Function

    Public Overrides Sub DeleteAnnouncement(ByVal ItemId As Integer)

        SqlHelper.ExecuteNonQuery(ConnectionString, DatabaseOwner & ObjectQualifier & "DeleteAnnouncement", ItemId)

    End Sub

    Public Overrides Sub AddAnnouncement(ByVal ModuleId As Integer, ByVal UserName As String, ByVal Title As String, ByVal URL As String, ByVal Syndicate As Boolean, ByVal ExpireDate As Date, ByVal Description As String, ByVal ViewOrder As Integer)

        SqlHelper.ExecuteNonQuery(ConnectionString, DatabaseOwner & ObjectQualifier & "AddAnnouncement", ModuleId, UserName, Title, URL, Syndicate, GetNull(ExpireDate), Description, GetNull(ViewOrder))

    End Sub

    Public Overrides Sub UpdateAnnouncement(ByVal ItemId As Integer, ByVal UserName As String, ByVal Title As String, ByVal URL As String, ByVal Syndicate As Boolean, ByVal ExpireDate As Date, ByVal Description As String, ByVal ViewOrder As Integer)

        SqlHelper.ExecuteNonQuery(ConnectionString, DatabaseOwner & ObjectQualifier & "UpdateAnnouncement", ItemId, UserName, Title, URL, Syndicate, GetNull(ExpireDate), Description, GetNull(ViewOrder))

    End Sub


posted @ 2006-07-31 11:04  dodo-yufan  阅读(640)  评论(1编辑  收藏  举报