我会尝试将所有数据访问逻辑放入数据访问层。理想情况下,这将位于单独的库和命名空间中,但并非必须如此。我会使用类,通常每个表/实体一个,并将所有类设计为无状态(因此您不必重用数据访问对象的同一实例,您可以在需要时随时实例化一个新实例访问数据库)。
我不会让它返回数组,而是让它返回数据对象(通常称为 DTO - 数据传输对象)。如果可能的话,我会保持 DTO 类尽可能干净,只包含公共属性而不包含方法。数据访问类都应该实现接口,以便可以创建每个接口的多个版本。一个用于 Access,一个用于 Oracle,一个用于 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
这可以通过使用一组可与任何数据库提供程序一起使用的数据访问对象来大大简化。为此,您只需要使用基本 ADO 类型,例如 IDbConnection 而不是 SqlConnection,以及 IDbCommand 而不是 SqlCommand。然后,只要 DataAccess 类需要一个,您的数据访问对象就可以请求一个可以创建新连接等的 DB Provider 工厂。但是,当您只是调用存储过程或其他东西时,这更容易做到。通常,尤其是当您在代码中动态构建 SQL 语句时,提供程序之间存在太多差异,因此您不能只对所有数据库提供程序使用相同的 DataAccess 类。
但是,这只是我...