开发者

Having trouble dealing with completely legit DBNULL. Using DataSets DataTables being passed as the Model data Views. ASP.NET MVC2

开发者 https://www.devze.com 2023-02-05 11:22 出处:网络
I\'m loving MVC but unfortunately all the tutorials, demos and ALL resources use Entity Framework to generate ViewData and most use LINQ to SQL instead of DataSets.

I'm loving MVC but unfortunately all the tutorials, demos and ALL resources use Entity Framework to generate ViewData and most use LINQ to SQL instead of DataSets.

I'm reusing existing business logic and the client (who is a great coder in his own right) wants to keep using Datasets... so i cant move away from these.

I have one table that contains columns which are allowed to be NULL in the database. When i try to access these...even to check if it's null i get an exception:

"The value for column 'FNN_CARRIERS_DESC' in table 'FNN_CARRIERS_DESC' is DBNull"

Now this is generated by the dataset.designer.vb file.

I know what you're going to say. "FNN_BRAND IS Null!!!" and that is true. But...follow the stack trace and the line in my code that is generating this error is this:

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

Guidance would be greatly appreciated! My inutition tells me this is not strictly an MVC problem but maybe something i don't understand about datasets.

This is the code in the reference.vb file that throws the 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_CARRIER开发者_如何学JAVAS_DESCColumn) = value
        End Set
    End Property

Things i've tried:

  • Commenting out the exception will make it return null which is what i want but the dataset will be rebuilt when the table changes or the stored procedure that generates the table result changes.
  • Changed the rules for the column on the datatable. actually yielded no result and will also be overridden on table regeneration.
  • IsNothing(column) or isDBnull(column) actually CAUSES the error because the column is being retrieved and casted.

I need to know the best way to solve this, hopefully keeping in with the MVC architecture.

Help me fellow nerds... you're my only hope!


OK so you have some existing data access logic which relies on data sets. That's perfectly fine (think of it that it could have been much worse like VB6 :-)). We all have to deal with legacy code. That's normal. Legacy code exists everywhere.

Although this is not a reason to pollute your shinning new MVC application with it. So here is what I would suggest you. Encapsulate this legacy code into some external repository which works with strong types only. Example:

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

and then implement:

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

Now your controller should never have to hear about datasets and crap like this:

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

You see. Now everything is clean and simple. Your view works with a strongly typed product object and shouldn't ever deal with datasets and datatables and exceptions like the one you are describing should never happen :-)


If anyone is interested i found a better solution... one that lets you keep using datasets without a layer in the middle.

A column is nullable the dataset actually provides a method for you.

Model.isFNN_CARRIERS_DESCNull()

so one could check the nullability of this column...without causing a crash.

0

精彩评论

暂无评论...
验证码 换一张
取 消