Avendo trattare problemi con DBNULL completamente legit. Uso DataSet DataTable vengono passati come dati di viste del modello. ASP.NET MVC2

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

Domanda

me ne sono innamorato MVC, ma purtroppo tutti i tutorial, demo e tutte le risorse utilizzare Entity Framework per generare Viewdata e la maggior parte l'uso LINQ to SQL, invece di DataSet.
Sto riutilizzando la logica di business esistente e il cliente (che è un grande codificatore in proprio) vuole continuare a utilizzare i set di dati ... quindi non posso spostare lontano da questi.

Ho una tabella che contiene le colonne che sono autorizzati ad essere NULL nel database. Quando provo ad accedere a questi ... anche per verificare se si tratta di nulla ottengo un'eccezione:

"Il valore per la colonna 'FNN_CARRIERS_DESC' nella tabella 'FNN_CARRIERS_DESC' è DBNull"

Ora, questo è generato dal file dataset.designer.vb.

So cosa stai per dire. "FNN_BRAND IS NULL !!!" e questo è vero. Ma ... seguire la traccia dello stack e la linea nel mio codice che genera questo errore è questo:

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

guida sarebbe molto apprezzato! Il mio inutition mi dice che questo non è strettamente un problema di MVC, ma forse qualcosa che non capisco su set di dati.

Questo è il codice nel file Reference.vb che genera l'eccezione:

<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

cose che ho provato:

  • Commentando l'eccezione renderà tornare nulla, che è quello che voglio, ma il set di dati verrà ricostruito quando cambia di tabella o la stored procedure che genera il risultato cambia tavolo.
  • cambiato le regole per la colonna sulla DataTable. in realtà dato alcun risultato e sarà anche essere sovrascritta sulla rigenerazione tavolo.
  • IsNothing (colonna) o IsDBNull (colonna) provoca effettivamente l'errore perché la colonna viene recuperata e colato.

Ho bisogno di sapere il modo migliore per risolvere questo, si spera tenendo con l'architettura MVC.

aiutarmi compagni secchioni ... Sei la mia unica speranza!

È stato utile?

Soluzione 2

Se qualcuno è interessato ho trovato una soluzione migliore ... uno che ti permette di mantenere con i set di dati senza strato in mezzo.

Una colonna è annullabile il set di dati in realtà fornisce un metodo per voi.

Model.isFNN_CARRIERS_DESCNull()

in modo si potrebbe verificare l'annullabilità di questa colonna ... senza causare un incidente.

Altri suggerimenti

OK in modo da avere una certa logica di accesso ai dati esistenti che si basa su insiemi di dati. Questo è perfettamente bene (si pensi è che avrebbe potuto essere molto peggio come VB6 :-)). Tutti noi abbiamo a che fare con il codice legacy. È normale. codice legacy esiste ovunque.

Anche se questo non è un motivo per inquinare la nuova applicazione MVC shinning con esso. Quindi, ecco quello che vorrei suggerire. Incapsulare questo codice legacy in qualche repository esterna che funziona solo con tipi forti. Esempio:

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

e quindi implementare:

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

Ora il controller non dovrebbe mai avere a sentir parlare di set di dati e merda come questo:

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

Si vede. Ora tutto è pulito e semplice. La vista funziona con un oggetto prodotto fortemente tipizzato e non deve mai trattare con serie di dati e DataTable ed eccezioni come quella che si sta descrivendo non dovrebbe mai accadere: -)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top