すべてのデータアクセスロジックをデータアクセス層に配置しようとします。理想的には、これは別のライブラリと名前空間にありますが、そうである必要はありません。私はクラスを使用します。通常はテーブル/エンティティごとに1つで、すべてのクラスがステートレスになるように設計します(したがって、データアクセスオブジェクトの同じインスタンスを再利用する必要はなく、必要なときにいつでも新しいインスタンスをインスタンス化できます。 DBにアクセスします)。
配列を返す代わりに、データオブジェクト(DTOと呼ばれることが多い-データ転送オブジェクト)を返すようにします。可能であれば、パブリックプロパティのみを含み、メソッドを含まないDTOクラスを可能な限りクリーンに保ちます。各データアクセスクラスの複数のバージョンを作成できるように、データアクセスクラスはすべてインターフェイスを実装する必要があります。1つはアクセス用、もう1つはOracle用、もう1つはSQL用などです。次に、データベースにアクセスする必要がある場合は常に(できれば、ビジネスレイヤーのみで、UIレイヤーではなく)、適切なデータアクセスオブジェクトを「一般的な"インターフェイスタイプ(これにより、ファクトリクラスが正しい具体的なデータアクセスオブジェクトタイプをビジネスオブジェクトに挿入する必要があります)。
DTOの実際の簡単な例を次に示します。
Public Class Employee
Public Id As Guid
Public Name As String
Public StartDate As Date
End Class
これがデータアクセスインターフェースの例です
Public Interface IEmployeeDataAccess
Function GetEmployee(id As Guid) As Employee
Function GetEmployees() As List(Of Employee)
End Interface
データアクセスクラスの例を次に示します。
Public Class SqlEmployeeDataAccess
Inherits IEmployeeDataAccess
Public Function GetEmployee(id As Guid) As Employee Implements IEmployeeDataAccess.GetEmployee
Dim employee As New Employee()
' Connect to SQL DB and populate employee DTO object
Return employee
End Function
Public Function GetEmployees() As List(Of Employee) Implements IEmployeeDataAccess.GetEmployees
Dim employees As New List(Of Employee)()
' Connect to SQL DB and populate list of employee DTO objects
Return employees
End Function
End Interface
次に、同様のクラスを呼び出しAccessEmployeeDataAccess
てOracleEmployeeDataAccess
、IEmployeeDataAccessインターフェイスも実装する場合があります。次に、データアクセス層でも、サポートされているDBプロバイダーごとにファクトリクラスを作成します。次のように、すべてのDataAccessファクトリに同じインターフェイスを実装させます。
Public Interface IDataAccessFactory
Function NewEmployeeDataAccess() As IEmployeeDataAccess
End Interface
Public Class SqlDataAccessFactory
Implements IDataAccessFactory
Public Function NewEmployeeDataAccess() As IEmployeeDataAccess
Return New SqlEmployeeDataAccess()
End Function
End Class
次に、私のビジネスクラスでは、次のようなことをするかもしれません。
Public Class EmployeeBusiness
Public Sub New(employeeDataAccess As IEmployeeDataAcess)
_employeeDataAccess = employeeDataAccess
End Sub
Private _employeeDataAccess As IEmployeeDataAcess
Public Function GetEmployee(id As Guid) As Employee
Return _employeeDataAccess.GetEmployee(id)
End Function
End Class
そして、私のビジネスファクトリーでは、次のようなことをします。
Public Class BusinessFactory
Public Sub New()
Select Case dataAccessType
Case "SQL"
_dataAccessFactory = New SqlDataAccessFactory()
Case "Oracle"
_dataAccessFactory = New OracleDataAccessFactory()
Case "Access"
_dataAccessFactory = New AccessDataAccessFactory()
End Select
End Sub
_dataAccessFactory As IDataAccessFactory
Public Function NewEmployeeBusiness() As IEmployeeBusiness
Return New EmployeeBusiness(_dataAccessFactory.NewEmployeeDataAccess())
End Function
End Class
これは、任意のデータベースプロバイダーと連携する単一のデータアクセスオブジェクトセットを使用することで大幅に簡素化できます。これを行うには、SqlConnectionの代わりにIDbConnection、SqlCommandの代わりにIDbCommandなどの基本ADOタイプのみを使用する必要があります。次に、データアクセスオブジェクトは、DataAccessクラスが接続を必要とするときはいつでも、新しい接続などを作成できるDBプロバイダーファクトリを要求できます。ただし、これは、単にストアドプロシージャなどを呼び出す場合に、より簡単に実行できます。多くの場合、特にSQLセンテンスをコードで動的に構築する場合、プロバイダー間の違いが多すぎるため、すべてのDBプロバイダーに同じDataAccessクラスを使用することはできません。
しかし、それは私だけです...