如何将UDT设置为null?

时间:2019-09-15 11:54:40

标签: c# vb.net oracle

我具有以下Oracle类型:

create or replace TYPE ActiveDaysOfTheWeek as object (Monday number, Tuesday number, Wednesday number, Thursday number, Friday number, Saturday number, Sunday number)

create or replace TYPE MonthlyReccurence as object (Days ActiveDaysOfTheWeek, Period number)

您可能会看到第二个对象使用第一个对象作为成员。

然后我有相应的.Net对象:

    <OracleCustomTypeMapping("MYSCHEMA.ACTIVEDAYSOFTHEWEEK")>
    Public Class ActiveDaysOfTheWeek
        Implements IOracleCustomTypeFactory
        Implements IOracleCustomType
        Implements INullable    

        Private Monday_Internal As Boolean
        Private Tuesday_Internal As Boolean
        ...

        Public Property Monday As Boolean
            Get
                Return Monday_Internal
            End Get
            Set(value As Boolean)
                Monday_Internal = value
            End Set
        End Property

    #Region "OracleProperties"
        <OracleObjectMappingAttribute("MONDAY")>
        Public Property Monday_Oracle As Integer
            Get
                Return CInt(IIf(Monday, 1, 0))
            End Get
            Set(value As Integer)
                Monday = (value = 1)
            End Set
        End Property
        ...
    #End Region

        Public Sub New()        
        End Sub

        Public Sub FromCustomObject(Connection As OracleConnection, Pointer As IntPtr) Implements IOracleCustomType.FromCustomObject
            OracleUdt.SetValue(Connection, Pointer, "MONDAY", Monday_Oracle)
            ...
        End Sub

        Public Sub ToCustomObject(Connection As OracleConnection, Pointer As IntPtr) Implements IOracleCustomType.ToCustomObject
            Monday_Oracle = CInt(OracleUdt.GetValue(Connection, Pointer, "MONDAY"))
            ...
        End Sub

        Public ReadOnly Property IsNull As Boolean Implements INullable.IsNull
            Get
                If Me.Monday Or Me.Tuesday Or Me.Wednesday Or Me.Thursday Or Me.Friday Or Me.Saturday Or Me.Sunday Then
                    Return False
                Else
                    Return True
                End If            
            End Get
        End Property

        Public Function CreateObject() As IOracleCustomType Implements IOracleCustomTypeFactory.CreateObject
            Return New ActiveDaysOfTheWeek
        End Function
    End Class

第二堂课

    <OracleCustomTypeMapping("MYSCHEMA.MONTHLYRECCURENCE")>
    Public Class MonthlyReccurence
        Implements IOracleCustomTypeFactory
        Implements IOracleCustomType
        Implements INullable

    #Region "PrivateProperties"
        private Days_Internal as ActiveDaysOfTheWeek
        private Period_Internal as integer
    #End Region

    #Region "PublicProperties"
        Public Property Days As ActiveDaysOfTheWeek
            Get
                Return Days_Internal
            End Get
            Set(value As ActiveDaysOfTheWeek)
                Days_Internal = value            
            End Set
        End Property

        Public Property Period As integer
            Get
                Return Period_Internal
            End Get
            Set(value As integer)
                Period_Internal = value
            End Set
        End Property    
    #End Region

    #Region "OracleProperties"
        <OracleObjectMappingAttribute("DAYS")>
        Public Property Days_Oracle As ActiveDaysOfTheWeek
            Get
                Return Days
            End Get
            Set(value As ActiveDaysOfTheWeek)
                Days = value
            End Set
        End Property

        <OracleObjectMappingAttribute("PERIOD")>
        Public Property Period_Oracle As Integer
            Get
                Return Period
            End Get
            Set(value As Integer)
                Period = value
            End Set
        End Property    
    #End Region

        Public Sub New()        
            Me.Days_Internal = new ActiveDaysOfTheWeek
            Me.Period_Internal = 0
        End Sub

        Public Sub FromCustomObject(Connection As OracleConnection, Pointer As IntPtr) Implements IOracleCustomType.FromCustomObject
            OracleUdt.SetValue(Connection, Pointer, "DAYS", Days_Oracle)
            OracleUdt.SetValue(Connection, Pointer, "PERIOD", Period_Oracle)        
        End Sub

        Public Sub ToCustomObject(Connection As OracleConnection, Pointer As IntPtr) Implements IOracleCustomType.ToCustomObject
            ActiveDaysOfTheWeek_Oracle = CType(OracleUdt.GetValue(Connection, Pointer, "DAYS"), ActiveDaysOfTheWeek)
            Period_Oracle = CInt(OracleUdt.GetValue(Connection, Pointer, "PERIOD"))        
        End Sub

        Public ReadOnly Property IsNull As Boolean Implements INullable.IsNull
            Get            
                If Me.Period_Internal > 0 then Return false
                Return true
            End Get
        End Property

        Public Function CreateObject() As IOracleCustomType Implements IOracleCustomTypeFactory.CreateObject
            Return New MonthlyReccurence
        End Function    
    End Class

现在,当我尝试将.Net应用程序中的数据插入到以 MonthlyReccurence 作为列的表中时,如果子字段ActiveDaysOfTheWeek不为null,则它将正常工作。

但是当子字段ActiveDaysOfTheWeek为null时,我有一个例外:自定义类型'ActiveDaysOfTheWeek'不实现要求'Null'。我不明白为什么会引发此异常,因为我的ActiveDaysOfTheWeek对象确实实现了IsNull属性。

(从.Net运行插入语句时会引发异常)

这是堆栈跟踪:

   at Oracle.DataAccess.Types.OracleUdt.GetObjData(OracleConnection con, IntPtr pUdt, Int32 attrIndex, OracleUdtStatus& status)
   at Oracle.DataAccess.Types.OracleUdt.GetData(OracleConnection con, IntPtr pUdt, Int32 index, OracleUdtStatus& status, Object& statusArray)
   at Oracle.DataAccess.Types.OracleUdt.GetValue(OracleConnection con, IntPtr pUdt, Int32 attrIndex, Object& statusArray)
   at Oracle.DataAccess.Types.OracleUdt.GetValue(OracleConnection con, IntPtr pUdt, String attrName, Object& statusArray)
   at Oracle.DataAccess.Types.OracleUdt.GetValue(OracleConnection con, IntPtr pUdt, String attrName)
   at MonthlyReccurence.ToCustomObject(OracleConnection Connection, IntPtr Pointer)   

有人知道问题出在哪里吗?

干杯, 谢谢

0 个答案:

没有答案