处理完全合法的 DBNULL 时遇到困难。使用数据集 数​​据表作为模型数据视图传递。 ASP.NET MVC2

发布于 2024-10-13 06:39:57 字数 1729 浏览 11 评论 0原文

我喜欢 MVC,但不幸的是所有教程、演示和所有资源都使用实体框架来生成 ViewData,并且大多数使用 LINQ to SQL 而不是数据集。
我正在重用现有的业务逻辑,而客户(他本身就是一位出色的编码员)希望继续使用数据集......所以我无法摆脱这些。

我有一张表,其中包含数据库中允许为 NULL 的列。当我尝试访问这些...甚至检查它是否为空时,我得到一个异常:

“表‘FNN_CARRIERS_DESC’中列‘FNN_CARRIERS_DESC’的值为 DBNull”

现在这是由 dataset.designer.vb 文件生成的。

我知道你要说什么。 “FNN_BRAND 为空!!!” 这是事实。 但是......按照堆栈跟踪和我的代码中生成此错误的行是这样的:

 <%= 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(column) 或 isDBnull(column) 实际上会导致错误,因为正在检索和转换列。

我需要知道解决这个问题的最佳方法,希望与 MVC 架构保持一致。

帮助我吧,书呆子们……你们是我唯一的希望!

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_CARRIERS_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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

明媚如初 2024-10-20 06:39:57

好的,您已经有了一些依赖于数据集的现有数据访问逻辑。这完全没问题(想想看,它可能会像 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

你看。现在一切都干净简单了。您的视图适用于强类型产品对象,并且不应该处理数据集和数据表,并且像您所描述的那样的异常永远不应该发生:-)

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 :-)

凤舞天涯 2024-10-20 06:39:57

如果有人感兴趣,我找到了一个更好的解决方案...一个可以让您继续使用数据集而无需中间层的解决方案。

列可以为空,数据集实际上为您提供了一种方法。

Model.isFNN_CARRIERS_DESCNull()

这样就可以检查该列的可为空性......而不会导致崩溃。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文