none
exception System.Data.StrongTypingException DBNull sur colonne AllowDBNull=true RRS feed

  • Question

  • Bonjour à tous,

    J'accède depuis un programme VB .Net 2008 à une table d'une base Access 2003.
    Ma table contient un champ date QLastScan avec Null autorisé dans Access, et AllowDBNull = true dans la DataColumn (dans le .xsd).

    Je cherche à lire une ligne de ma manière suivante:

    Friend Structure FolderDBProperties
    Dim ScanFolder As Boolean
    Dim ScanFolderTree As Boolean
    Dim LastScan As Nullable(Of Date)
    Dim LastActivity As Date
    Dim ItemsCount As Integer
    End Structure

    Dim DBProperties As FolderDBProperties
    Dim MyRow As QFolderRow = GetFolderRow(Folder)
    With DBProperties
    .LastActivity = MyRow.QLastActivity
    .LastScan = MyRow.QLastScan
    .ScanFolder = MyRow.QScanFolder
    .ScanFolderTree = MyRow.QScanFolderTree
    .ItemsCount = MyRow.QItemsCount
    End With

    Et je me trouve confronté à l'erreur suivante:

    System.Data.StrongTypingException: La valeur pour la colonne 'QLastScan' dans la table 'QFolder' est DBNull. ---> System.InvalidCastException: La conversion du type 'DBNull' en type 'Date' n'est pas valide.
    à Microsoft.VisualBasic.CompilerServices.Conversions.ToDate(Object Value)
    à Quinoa.Data.QUserDataMgr.QFolderRow.get_QLastScan() dans C:\Documents and Settings\cbourgeois\Mes documents\Visual Studio 2008\Projects\Quinoa\Quinoa\Data\QUserDataMgr.Designer.vb:ligne 1687
    --- Fin de la trace de la pile d'exception interne ---
    à Quinoa.Data.QUserDataMgr.QFolderRow.get_QLastScan() dans C:\Documents and Settings\cbourgeois\Mes documents\Visual Studio 2008\Projects\Quinoa\Quinoa\Data\QUserDataMgr.Designer.vb:ligne 1689

    Dans le .xsd, un autre propriété de ma colonne est NullValue = (Throw exception)
    Lorsque j'essaye de modifier ce paramètre, j'ai l'erreur : "Valeur de propriété non valide", "La valeur entrée n'est pas valide pour le type de données actuel."

    Comment faire comprendre à VB que mon champ peut être null et qu'il ne doit pas générer d'erreur dans ce cas ?
    merci d'avance pour votre aide !

    Cédric.

















    lundi 8 décembre 2008 10:49

Réponses

  • Bonjour,

     

    Les DataSet typé généré par Visual Studio ne supporte pas les colonnes purement Nullable au sens de .NET (Pour garder la compatibilité du .NET Framework 1.1).

    Lorsque vous autorisez du Nullable au sens des DataSet, .NET met en fait une valeur spéciale pour représente le NULL des SGBD. Cette valeur est tout simplement le singleton DBNull.Value.

     

    Or, vous ne pouvez pas mettre :

    myRow.QLastScan = DBNull.Value

    ou

    If myRow.QLastScan = DBNull.Value Then

    ...

    End If

     

    Tout simplement parceque le type Date est différent de DBNull.Value (au sens du .NET Framework).

    Lors de la génération de votre DataSet typé, Visual Studio génére pour les colonne Nullable (au sens DataSet/SGBD) 2 méthode dans les classes "Row" :

    • IsXXXXXNull()
    • SetXXXXXNull()

    Où XXXXX est le nom de la colonne. La première méthode permet de tester si la valeur est à DBNull.Value et l'autre pour mettre la valeur à NULL.

     

    Vous devez utiliser ces 2 méthodes pour manipuler les colonnes Nullable (au sens DataSet/SGBD).

     

    Cordialement

    mercredi 10 décembre 2008 21:25
    Modérateur

Toutes les réponses

  • Bonjour,

     

    Tout simplement parceque vous ne pouvez pas mettre DBNull.Value dans un type DateTime :

    Code Snippet

     

    If MyRow.IsQLastScanNull() Then

    'QLastScan est null

    Else

    'QLastScan n'est pas null

    DBProperties.LastScan = MyRow.QLastScan

    End If

     

     

    Dans le .xsd, un autre propriété de ma colonne est NullValue = (Throw exception)
    Lorsque j'essaye de modifier ce paramètre, j'ai l'erreur : "Valeur de propriété non valide", "La valeur entrée n'est pas valide pour le type de données actuel."

    Pouvez-vous nous indiquer quel est le type de votre colonne ?

     

    Cordialement

     

    lundi 8 décembre 2008 20:27
    Modérateur
  • Bonjour, et merci pour votre réponse.

    Dans la base Access, le champ est de type "Date/Heure", et Null interdit est à "Non".
    Dans mon DataRow, le champ QLastScan est de type Date (et pas Nullable(of Date)...)

    A l'origine, ce champ était à null interdit dans la base de données, et je l'ai changé récemment, en répercutant les modifications dans la DataTable (AllowDBNull = true) et dans la requête principale du table adapter. J'ai même supprimé et réimporté le champ sans plus de succès.

    Merci d'avance pour votre aide.

    Cordialement,

    Cédric.
    mardi 9 décembre 2008 10:20
  • Pour compéter mon message précédent :
    dans ma structure, me champ LastScan est Nullable(Of Date), ce qui fait qu'il ne devrait pas y avoir d'erreur à l'affectation.
    De plus, l'erreur se produit plus tôt, à l'intérieur du code généré par VB :
    QUserDataMgr.Designer.vb:ligne 1687

    En effet, la propriété QLastScan de ma DataRow (QFolderRow) est typée en Date et non en Nullable (Of Date):

    Code Snippet
                <Global.System.Diagnostics.DebuggerNonUserCodeAttribute()>  _
                Public Property QLastScan() As Date
                    Get
                        Try
                            Return CType(Me(Me.tableQFolder.QLastScanColumn),Date)
                        Catch e As Global.System.InvalidCastException
                            Throw New Global.System.Data.StrongTypingException("La valeur pour la colonne 'QLastScan' dans la table 'QFolder' est DBNull.", e)
                        End Try
                    End Get
                    Set
                        Me(Me.tableQFolder.QLastScanColumn) = value
                    End Set
                End Property

     

     

    et c'est là que l'erreur se produit.

     

    Reste à savoir comment faire pour que ce code soit modifié proprement.

     

    Merci d'avance !

     

    Cédric.

    mercredi 10 décembre 2008 12:40
  • Bonjour,

     

    Les DataSet typé généré par Visual Studio ne supporte pas les colonnes purement Nullable au sens de .NET (Pour garder la compatibilité du .NET Framework 1.1).

    Lorsque vous autorisez du Nullable au sens des DataSet, .NET met en fait une valeur spéciale pour représente le NULL des SGBD. Cette valeur est tout simplement le singleton DBNull.Value.

     

    Or, vous ne pouvez pas mettre :

    myRow.QLastScan = DBNull.Value

    ou

    If myRow.QLastScan = DBNull.Value Then

    ...

    End If

     

    Tout simplement parceque le type Date est différent de DBNull.Value (au sens du .NET Framework).

    Lors de la génération de votre DataSet typé, Visual Studio génére pour les colonne Nullable (au sens DataSet/SGBD) 2 méthode dans les classes "Row" :

    • IsXXXXXNull()
    • SetXXXXXNull()

    Où XXXXX est le nom de la colonne. La première méthode permet de tester si la valeur est à DBNull.Value et l'autre pour mettre la valeur à NULL.

     

    Vous devez utiliser ces 2 méthodes pour manipuler les colonnes Nullable (au sens DataSet/SGBD).

     

    Cordialement

    mercredi 10 décembre 2008 21:25
    Modérateur
  • Bonjour Gilles, et merci pour votre aide.

    Vos explications m'ont permis de résoudre ce problème et de mieux comprendre le fonctionnement du framework.

    Cordialement,

    Cédric.
    jeudi 11 décembre 2008 23:09