投稿者 るきお  (社会人) 投稿日時 2022/6/10 21:29:36
> るきおさんは直接コードに書かれるということですが、インテリセンスが無くて不便ではないですか?
あったら便利だなとは思いますが、あきらめて受け入れています。
複雑なクエリはSSDさんと同様でツールで作成したものをVisual Studioに貼り付けたりします。
私の場合は、SQL Server Management Studioを使う場合が多いです。

>"データアクセス層の外"とはどこのことでしょうか?
>"モデルとしてデータを公開する"とは具体的に何が何をすることでしょうか?
たとえば、このようにプロジェクトを3つに分けます。(業務ロジック専用のプロジェクトや、WebAPIの通信用のプロジェクトなどさらに分ける場合もあります。)


MySampleSystem.Modelプロジェクトには主に業務で使用するデータ構造だけを記したシンプルなクラスを定義します。これを「モデル」と呼びます。たとえば、このような感じです。
''' <summary>商品</summary> 
Public Class Product

    ''' <summary>商品コード</summary> 
    Public Property ProductCode As String

    ''' <summary>商品名</summary> 
    Public Property ProductName As String

    ''' <summary>現行品区分</summary> 
    Public Property IsActive As Boolean

End Class


MySampleSystem.DataAccessプロジェクトはデータアクセス層です。データベースにアクセスするプログラムはすべてここに記述します。
たとえば、このような感じです。
Public Class ProductAccess

    ''' <summary>商品コードを指定して、該当する商品を取得します。</summary> 
    Public Function GetProduct(productCode As StringAs Model.Product

        Using command As New Microsoft.Data.SqlClient.SqlCommand
            command.CommandText = "SELECT * FROM T_PRODUCT WHERE productCode = @productCode"
            command.Parameters.Add("@productCode", Data.SqlDbType.NVarChar).Value = productCode

            Using table As Data.DataTable = DbUtil.Select(command)

                Dim result As New Model.Product
                result.ProductCode = CStr(table.Rows(0)("ProductCode"))
                result.ProductName = CStr(table.Rows(0)("ProductName"))
                result.IsActive = CBool(table.Rows(0)("IsActive"))

                Return result
            End Using
        End Using

    End Function

    ''' <summary>商品コードから商品を検索します。該当する商品の一覧を返します。</summary> 
    ''' <param name="partOfproductCode">検索する商品コードの一部</param> 
    Public Function FindProduct(partOfproductCode As StringAs List(Of Model.Product)

        Using command As New Microsoft.Data.SqlClient.SqlCommand
            command.CommandText = "SELECT * FROM T_PRODUCT WHERE productCode LIKE CONCAT( N'%', @productCode, N'%' )"
            command.Parameters.Add("@productCode", Data.SqlDbType.NVarChar).Value = partOfproductCode

            Using table As Data.DataTable = DbUtil.Select(command)

                Dim results As New List(Of Model.Product)
                For Each row As Data.DataRow In table.Rows
                    Dim result As New Model.Product
                    result.ProductCode = CStr(row("ProductCode"))
                    result.ProductName = CStr(row("ProductName"))
                    result.IsActive = CBool(row("IsActive"))
                    results.Add(result)
                Next
                Return results
            End Using
        End Using

    End Function

End Class


MySampleSystem.WinUIプロジェクトはUI層です。
データを操作する場合、このプロジェクトでは直接データベースにアクセスするのではなく、データアクセス層(MySampleSystem.DataAccess)に依頼します。
たとえば、このような感じです。
Private Sub btnSearch_Click(sender As Object, e As EventArgs) Handles btnSearch.Click

    Dim productAccess As New DataAccess.ProductAccess

    Dim results As List(Of Model.Product) = productAccess.FindProduct(txtProductCode.Text)

    MsgBox($"{results.Count} 件ヒットしました。")
    MsgBox($"1件目 {results(0).ProductName}")

End Sub


この構造によってUI層はデータベースとは完全に切り離され、ただ Model.Product というクラス(モデル)を介してのみデータと接点を持つことになります。

これが「モデルとしてデータを公開する」という意味です。
「データアクセス層の外」とはUI層など、別のレイヤーを指します。

システムをこのような構造にすることで、デバッグや分業がやりやすくなり、コードの再利用や、機能追加・保守などの柔軟性が高まります。
たとえば、後になってWeb用の画面も作りたいと思った場合、データアクセス層はそのまま流用できます。
データベースの項目の大きな変更があった場合、データアクセス層のプログラムだけ変更・テストすれば、UI層は無影響で済むかもしれません。
開発中によくわからないバグが発生しているときに、データの取得に問題があるのか、画面の制御に問題があるのか、問題を切り分けやすくなります。