Возникли проблемы при работе с полностью законным DBNULL.Использование DataSets DataTables, передаваемые как представления данных модели.ASP.NET MVC2 - PullRequest
1 голос
/ 20 января 2011

Мне нравится MVC, но, к сожалению, все учебники, демонстрации и ВСЕ ресурсы используют Entity Framework для генерации ViewData и большинство используют LINQ to SQL вместо DataSets.
Я повторно использую существующую бизнес-логику, и клиент (который сам по себе является хорошим программистом) хочет продолжать использовать наборы данных ... поэтому я не могу отойти от них.

У меня есть одна таблица, которая содержит столбцы, которым разрешено быть пустыми в базе данных. Когда я пытаюсь получить доступ к ним ... даже для проверки, если он нулевой, я получаю исключение:

"Значение столбца 'FNN_CARRIERS_DESC' в таблице 'FNN_CARRIERS_DESC' равно DBNull"

Теперь это генерируется файлом dataset.designer.vb.

Я знаю, что ты собираешься сказать. "FNN_BRAND IS НУЛЬ !!!" и это правда. Но ... следуйте трассировке стека, и строка в моем коде, которая генерирует эту ошибку, такова:

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

Руководство будет с благодарностью! Моя интуиция говорит мне, что это не просто проблема MVC, но, может быть, я чего-то не понимаю в наборах данных.

Это код в файле reference.vb, который выдает исключение:

<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

Вещи, которые я пробовал:

  • Если закомментировать исключение, оно вернет значение null, чего я и хочу, но набор данных будет перестроен при изменении таблицы или при изменении хранимой процедуры, генерирующей результат таблицы.
  • Изменены правила для столбца данных. фактически не дало никакого результата и также будет переопределено при регенерации таблицы.
  • IsNothing (столбец) или isDBnull (столбец) фактически ВЫЗЫВАЕТ ошибку, поскольку столбец извлекается и преобразуется.

Мне нужно знать, как решить эту проблему, надеясь, что она будет соответствовать архитектуре MVC.

Помоги мне, ботаны ... ты моя единственная надежда!

Ответы [ 2 ]

1 голос
/ 20 января 2011

ОК, так что у вас есть логика доступа к данным, основанная на наборах данных.Это прекрасно (подумайте, что могло быть намного хуже, чем в VB6 :-)).Нам всем приходится иметь дело с устаревшим кодом.Это нормально.Устаревший код существует везде.

Хотя это не причина загрязнять ваше сверкающее новое приложение MVC этим.Так вот, что я хотел бы предложить вам.Инкапсулируйте этот устаревший код в некоторый внешний репозиторий, который работает только со строгими типами.Пример:

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

и затем реализовать:

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

Теперь ваш контроллер никогда не должен слышать о наборах данных и дерьме, как это:

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

Вы видите,Теперь все чисто и просто.Ваше представление работает со строго типизированным объектом продукта и никогда не должно иметь дело с наборами данных, таблицами данных и исключениями, подобными описанным вами, которые никогда не должны происходить: -)

0 голосов
/ 14 сентября 2011

Если кому-то интересно, я нашел лучшее решение ... которое позволит вам продолжать использовать наборы данных без слоя в середине.

Столбец обнуляется, набор данных фактически предоставляет метод для вас.

Model.isFNN_CARRIERS_DESCNull()

чтобы можно было проверить обнуляемость этого столбца ... без сбоев.

...