Ayant du mal à traiter avec DBNULL complètement légitime. En utilisant des données DataTables sont passés les vues de données du modèle. ASP.NET MVC2

StackOverflow https://stackoverflow.com/questions/4744868

Question

Je suis amoureuse de MVC, mais malheureusement les tutoriels, des démos et des ressources utilisent tous Entity Framework pour générer ViewData et plus utiliser LINQ to SQL au lieu de DataSets.
Je réutiliser la logique métier existante et le client (qui est un grand codeur dans son propre droit) veut continuer à utiliser ... datasets donc je ne peux pas déplacer loin de ces derniers.

J'ai une table qui contient des colonnes qui sont autorisés à être NULL dans la base de données. Quand je tente d'accéder à ces ... même pour vérifier si elle est nulle que je reçois une exception:

  

"La valeur pour la colonne 'FNN_CARRIERS_DESC' table 'FNN_CARRIERS_DESC' est DBNull"

Maintenant cela est généré par le fichier dataset.designer.vb.

Je sais ce que vous allez dire. « FNN_BRAND est nul !!! » et cela est vrai. Mais ... suivre la trace de la pile et la ligne dans mon code qui génère cette erreur est la suivante:

 <%= Html.TextBox("FNN_CARRIERS_DESCTextBox", If(IsNothing(Model.FNN_CARRIERS_DESC), Model.FNN_CARRIERS_DESC, ""))%>

orientation serait grandement appréciée! Mon inutition me dit que ce n'est pas strictement un problème MVC mais peut-être quelque chose que je ne comprends pas les ensembles de données.

Ceci est le code dans le fichier Reference.vb qui lève l'exception:

<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(),  _
     Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")>  _
    Public Property FNN_CARRIERS_DESC() As String
        Get
            Try 
                Return CType(Me(Me.tableVIT_FNN_CommsService.FNN_CARRIERS_DESCColumn),String)
            Catch e As Global.System.InvalidCastException
                Throw New Global.System.Data.StrongTypingException("The value for column 'FNN_CARRIERS_DESC' in table 'VIT_FNN_CommsService' is DBNul"& _ 
                        "l.", e)
            End Try
        End Get
        Set
            Me(Me.tableVIT_FNN_CommsService.FNN_CARRIERS_DESCColumn) = value
        End Set
    End Property

Les choses que j'ai essayé:

  • Commentant l'exception va le faire revenir nulle qui est ce que je veux, mais l'ensemble de données sera reconstruit lorsque les changements de table ou la procédure stockée qui génère le résultat change de table.
  • Changé les règles de la colonne datatable. en réalité n'a donné aucun résultat et sera également surchargée sur la régénération de la table.
  • IsNothing (colonne) ou IsDBNull (colonne) fait l'erreur PROVOQUE parce que la colonne est récupéré et casté.

Je dois connaître la meilleure façon de résoudre ce problème, nous l'espérons garder dans l'architecture MVC.

Aidez-moi à d'autres tarés ... tu es mon seul espoir!

Était-ce utile?

La solution 2

Si quelqu'un est intéressé j'ai trouvé une meilleure solution ... qui vous permet de continuer à utiliser des jeux de données sans une couche au milieu.

Une colonne est annulable l'ensemble de données fournit en fait une méthode pour vous.

Model.isFNN_CARRIERS_DESCNull()

on pourrait donc vérifier la valeur NULL de cette colonne ... sans provoquer un accident.

Autres conseils

OK si vous avez une logique d'accès aux données existantes qui repose sur des ensembles de données. C'est parfaitement bien (pensez à ce que cela aurait pu être bien pire comme VB6 :-)). Nous avons tous à traiter avec le code existant. C'est normal. L'ancien code existe partout.

Bien que ce n'est pas une raison de polluer votre nouvelle application MVC shinning avec elle. Voici donc ce que je vous suggère. Encapsulate ce code dans un certain héritage référentiel externe qui fonctionne avec des types forts seulement. Exemple:

Public Interface IProductsRepository
    Function GetProduct(id As Integer) As Product
End Interface

et puis mettre en œuvre:

Public Class LegacyProductsRepository
    Implements IProductsRepository
    Public Function GetProduct(id As Integer) As Product
        ' TODO: call your legacy code here and convert the datasets
        ' and datatables you were dealing with into a nice strongly
        ' typed model object
    End Function
End Class

Maintenant, votre contrôleur ne devrait jamais avoir à entendre parler des jeux de données et de la merde comme ceci:

Public Class ProductsController
    Inherits Controller
    Private ReadOnly _repository As IProductsRepository
    Public Sub New(repository As IProductsRepository)
        _repository = repository
    End Sub

    Public Function Show(id As Integer) As ActionResult
        Dim product = _repository.GetProduct(id)
        Return View(product)
    End Function
End Class

Vous voyez. Maintenant, tout est propre et simple. Votre point de vue fonctionne avec un objet produit fortement typé et ne devrait jamais traiter des ensembles de données et datatables et exceptions comme celui que vous décrivez ne devrait jamais se produire: -)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top