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
-
13-10-2019 - |
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!
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: -)