1

나는 MVC를 좋아하지만 불행히도 모든 자습서, 데모 및 모든 리소스는 Entity Framework를 사용하여 ViewData를 생성하고 DataSet 대신 LINQ to SQL을 사용합니다.
저는 기존 비즈니스 로직을 재사용하고 클라이언트 (자신의 권리로 훌륭한 코더)는 데이터 세트를 계속 사용하려고합니다 ... 그래서 이것들을 벗어날 수 없습니다.완전히 합법적 인 DBNULL을 처리하는 데 문제가 있습니다. 모델 데이터보기로 전달되는 DataSets DataTables 사용. ASP.NET MVC2

데이터베이스에 NULL이 허용되는 열을 포함하는 테이블이 하나 있습니다. 이제이

"테이블 'FNN_CARRIERS_DESC'에서 열 'FNN_CARRIERS_DESC'DBNull이 있습니다에 대한 값"내가 ...이 액세스하려고 할 때이 null의 경우도 내가 예외가 확인 dataset.designer.vb 파일에 의해 생성됩니다.

나는 당신이 할 말을 알고 있습니다. "FNN_BRAND IS Null !!!" 사실입니다. 지침은 크게 감상 할 수

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

: 하지만 ... 스택 추적이 오류를 생성 내 코드의 라인을 따라이입니다! 필자의 주장은 이것이 MVC의 문제가 아니라 데이터 세트에 대해 이해하지 못하는 것임을 말해 준다. 내가 시도했습니다

<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을 반환 할 것입니다

    예외를 던지는 reference.vb 파일의 코드 테이블의 변경 또는 테이블 결과를 생성하는 저장 프로 시저가 변경되면 데이터 집합이 다시 작성되기를 원합니다.
  • 데이터 테이블의 열에 대한 규칙이 변경되었습니다. 실제로 아무런 결과도 산출되지 않았고 테이블 재생성에서도 무시됩니다.
  • IsNothing (열) 또는 isDBnull (열) 열을 검색하고 캐스팅하기 때문에 실제로 오류가 발생합니다.

MVC 아키텍처를 유지하면서이를 해결하는 가장 좋은 방법을 알아야합니다.

나를 괴롭히지 마라 ... 너는 내 유일한 희망이야!

답변

0

더 좋은 해결책을 찾은 사람은 ... 하나 중간에 레이어가없는 데이터 세트를 계속 사용할 수 있습니다.

열이 nullable 인 경우 데이터 집합이 실제로 메서드를 제공합니다.

Model.isFNN_CARRIERS_DESCNull() 

이렇게하면이 열의 null 가능성을 확인할 수 있습니다. 충돌을 일으키지 않습니다.

1

그래, 데이터 세트를 사용하는 기존의 데이터 액세스 논리가 있습니다. 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

고객에게 설명 할 때 Korz가 솔루션을 바꿀 수도 있지만 이는 분명 좋은 조언입니다 .-) –

+0

Cool ok 그래서 이것이 뷰 모델이라고합니다. – korz

+0

@korz, 정확하지는 않습니다. 뷰 모델은 모델 (이 경우 제품)과 뷰 사이에있는 항목입니다. 주어진 뷰의 필요에 맞게 특별히 맞춤 설정된 클래스입니다. 예를 들어, Product 모델에 10 개의 속성이 있지만 그 중 두 개만 표시하고보기에 표시하려면 구체적으로 형식화해야 ProductViewModel 클래스를 작성해야합니다. 그런 다음 컨트롤러는 제품 모델과 뷰 모델을 매핑하고 뷰 모델을 뷰에 전달합니다. 예제에서 모델을 나쁜 관행이지만 뷰의 목적을 달성하기에 충분하도록 직접 전달했습니다. –