1

私は MVC が大好きですが、残念ながらすべてのチュートリアル、デモ、およびすべてのリソースで Entity Framework を使用して ViewData を生成し、ほとんどの場合、DataSet の代わりに LINQ to SQL を使用しています。
私は既存のビジネス ロジックを再利用しており、クライアント (彼自身が優れたコーダーである) はデータセットを使い続けたいと考えているため、これらから離れることはできません。

データベースで NULL が許可されている列を含むテーブルが 1 つあります。これらにアクセスしようとすると、null かどうかを確認するために例外が発生します。

「テーブル 'FNN_CARRIERS_DESC' の列 'FNN_CARRIERS_DESC' の値は DBNull です」

これは、dataset.designer.vb ファイルによって生成されます。

私はあなたが何を言おうとしているのか知っています。"FNN_BRAND IS Null!!!" そしてそれは本当です。しかし...スタックトレースに従ってください。このエラーを生成しているコードの行は次のとおりです。

 <%= 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 アーキテクチャを維持する必要があります。

仲間のオタクを助けてください... あなたは私の唯一の希望です!

4

2 に答える 2

1

OK、データセットに依存する既存のデータアクセスロジックがあります。それは完全に問題ありません(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

分かりますか。これで、すべてがクリーンでシンプルになりました。ビューは強く型付けされた製品オブジェクトで機能し、データセットやデータテーブルを処理するべきではありません。また、説明しているような例外は決して発生しないはずです:-)

于 2011-01-20T08:35:41.307 に答える
0

誰かが興味を持っているなら、私はより良い解決策を見つけました...真ん中にレイヤーなしでデータセットを使い続けることができるものです。

列は null 可能で、データセットは実際にメソッドを提供します。

Model.isFNN_CARRIERS_DESCNull()

そのため、クラッシュを引き起こすことなく、この列の null 可能性を確認できます。

于 2011-09-14T09:56:17.980 に答える