ORM(二)数据层的定义和实现。
在上一节中我们讲述了对OQL接口的定义和介绍。有了这部份的支持,我们今天来看看对数据操作的接口定义。
上面显示的数据提供器IDataProvider它直接继承了.Net框架的IDbCommand接口,我现在不知道为什么这样定义了,不知道这样定义有没有问题。
下面是对IDataProvider实现在的SQLServerDataProvider类。
Public Class SQLServerDataProvider
Implements Lily.Core.DataProvider.IDataProvider
#Region "成员变量"
Private md_Command As SqlClient.SqlCommand
Private md_Connection As SqlClient.SqlConnection
Private md_Tran As SqlClient.SqlTransaction
'是否自动关闭连接
Private md_blnAutoCloseConnection As Boolean = True
#End Region
#Region "类实例化"
''' -----------------------------------------------------------------------------
''' <summary>
''' 类实例化.
''' </summary>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Private Sub New()
End Sub
''' -----------------------------------------------------------------------------
''' <summary>
''' 类实例化
''' </summary>
''' <param name="connection">实例化所使用的连接对象.</param>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Sub New(ByVal connection As SqlClient.SqlConnection)
Me.InitConnection(connection)
End Sub
''' -----------------------------------------------------------------------------
''' <summary>
''' 类实例化.
''' </summary>
''' <param name="connectionString">连接字符串</param>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Sub New(ByVal connectionString As String)
Dim conn As New SqlClient.SqlConnection(connectionString)
Me.InitConnection(conn)
End Sub
'数据对象初始化
Private Sub InitConnection(ByVal connection As IDbConnection)
'连接对象
Me.md_Connection = connection
'创建命令对象
Me.md_Command = New SqlClient.SqlCommand
'命令对象的默认命令类型
Me.md_Command.CommandType = CommandType.Text
End Sub
#End Region
#Region "类公共属性"
#End Region
#Region "IDataProvider接口实现"
''' -----------------------------------------------------------------------------
''' <summary>
''' 开始一个事务.
''' </summary>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Sub BeginTransaction() Implements IDataProvider.BeginTransaction
Me.Open()
Me.Transaction = Me.Connection.BeginTransaction
End Sub
''' -----------------------------------------------------------------------------
''' <summary>
''' 关闭连接.
''' </summary>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Sub Close() Implements IDataProvider.Close
If Me.md_Connection Is Nothing Then
Return
Else
If Not Me.Command Is Nothing Then
Me.Command.Parameters.Clear()
End If
'连接没有打开
If Me.md_Connection.State <> ConnectionState.Open Then
Return
Else
'当前实例没有开启事务
If Me.Transaction Is Nothing Then
'自动关闭连接
If Me.AutoCloseConnection Then
Me.md_Connection.Close()
End If
End If
End If
End If
End Sub
''' -----------------------------------------------------------------------------
''' <summary>
''' 提交事务.
''' </summary>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Sub Commit() Implements IDataProvider.Commit
Me.Transaction.Commit()
Me.Close()
End Sub
''' -----------------------------------------------------------------------------
''' <summary>
''' 把查询结果填充到datatable对象
''' </summary>
''' <param name="datatable">要填充的datatable对象.</param>
''' <returns></returns>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Overloads Function Fill(ByVal datatable As System.Data.DataTable) As Integer Implements IDataProvider.Fill
Try
Me.Open()
DebugCommandText()
Dim da As SqlClient.SqlDataAdapter = New SqlClient.SqlDataAdapter(Me.Command)
Return da.Fill(datatable)
Catch ex As Exception
Throw New Lily.core.DataProvider.DataProviderException(ex.Message, ex)
Finally
Me.Close()
End Try
End Function
''' -----------------------------------------------------------------------------
''' <summary>
''' 把查询结果填充到datatset对象
''' </summary>
''' <param name="datatset">要填充的datatset对象.</param>
''' <returns></returns>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Overloads Function Fill(ByVal datatset As System.Data.DataSet) As Integer Implements IDataProvider.Fill
Try
Me.Open()
Dim da As SqlClient.SqlDataAdapter = New SqlClient.SqlDataAdapter(Me.Command)
DebugCommandText()
Return da.Fill(datatset)
Catch ex As Exception
Throw New Lily.core.DataProvider.DataProviderException(ex.Message, ex)
Finally
Me.Close()
End Try
End Function
''' -----------------------------------------------------------------------------
''' <summary>
''' 打开连接.
''' </summary>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Sub Open() Implements IDataProvider.Open
If Me.md_Connection.State <> ConnectionState.Open Then
Me.md_Connection.Open()
End If
End Sub
''' -----------------------------------------------------------------------------
''' <summary>
''' 回滚事务.
''' </summary>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Sub Rollback() Implements IDataProvider.Rollback
Me.Transaction.Rollback()
Me.Close()
End Sub
''' -----------------------------------------------------------------------------
''' <summary>
''' 试图取消命令的执行.
''' </summary>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Sub Cancel() Implements System.Data.IDbCommand.Cancel
Me.Command.Cancel()
End Sub
''' -----------------------------------------------------------------------------
''' <summary>
''' 获取或设置针对数据源运行的文本命令。
''' </summary>
''' <value></value>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Property CommandText() As String Implements System.Data.IDbCommand.CommandText
Get
Return Me.Command.CommandText
End Get
Set(ByVal Value As String)
Me.Command.CommandText = Value
End Set
End Property
''' -----------------------------------------------------------------------------
''' <summary>
''' 获取或设置在终止执行命令的尝试并生成错误之前的等待时间。
''' </summary>
''' <value></value>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Property CommandTimeout() As Integer Implements System.Data.IDbCommand.CommandTimeout
Get
Return Me.Command.CommandTimeout
End Get
Set(ByVal Value As Integer)
Me.Command.CommandTimeout = Value
End Set
End Property
''' -----------------------------------------------------------------------------
''' <summary>
''' 指示或指定如何解释CommandText 属性。
''' </summary>
''' <value></value>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Property CommandType() As System.Data.CommandType Implements System.Data.IDbCommand.CommandType
Get
Return Me.Command.CommandType
End Get
Set(ByVal Value As System.Data.CommandType)
Me.Command.CommandType = Value
End Set
End Property
''' -----------------------------------------------------------------------------
''' <summary>
''' 获取或设置IDbCommand 的此实例使用的
''' </summary>
''' <value></value>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Property Connection() As System.Data.IDbConnection Implements System.Data.IDbCommand.Connection
Get
Return Me.md_Connection
End Get
Set(ByVal Value As System.Data.IDbConnection)
md_Connection = Value
End Set
End Property
''' -----------------------------------------------------------------------------
''' <summary>
''' 创建一个参数对象.已设置了参数名称,参数的名称是根据GUID产生的避免了重复.
''' </summary>
''' <returns></returns>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Overloads Function CreateParameter() As System.Data.IDbDataParameter Implements System.Data.IDbCommand.CreateParameter
Return Me.Command.CreateParameter
End Function
''' -----------------------------------------------------------------------------
''' <summary>
''' 针对.NET Framework 数据提供程序的Connection 对象执行SQL 语句,并返回受影响的行数。
''' </summary>
''' <returns></returns>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Function ExecuteNonQuery() As Integer Implements System.Data.IDbCommand.ExecuteNonQuery
Try
Me.Open()
DebugCommandText()
Dim i As Integer = Me.Command.ExecuteNonQuery
Return i
Catch ex As Exception
Throw New Lily.core.DataProvider.DataProviderException(ex.Message, ex)
Finally
Me.Close()
End Try
End Function
''' -----------------------------------------------------------------------------
''' <summary>
''' 已重载。针对Connection 执行CommandText,并生成IDataReader。
''' </summary>
''' <returns></returns>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Overloads Function ExecuteReader() As System.Data.IDataReader Implements System.Data.IDbCommand.ExecuteReader
Try
Me.Open()
DebugCommandText()
Return Me.Command.ExecuteReader
Catch ex As Exception
Throw New Lily.core.DataProvider.DataProviderException(ex.Message, ex)
End Try
End Function
''' -----------------------------------------------------------------------------
''' <summary>
''' 已重载。针对Connection 执行CommandText,并生成IDataReader。
''' </summary>
''' <param name="behavior"></param>
''' <returns></returns>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Overloads Function ExecuteReader(ByVal behavior As System.Data.CommandBehavior) As System.Data.IDataReader Implements System.Data.IDbCommand.ExecuteReader
Try
Me.Open()
DebugCommandText()
Return Me.Command.ExecuteReader(behavior)
Catch ex As Exception
Throw New Lily.Core.DataProvider.DataProviderException(ex.Message, ex)
End Try
End Function
''' -----------------------------------------------------------------------------
''' <summary>
''' 执行查询,并返回查询所返回的结果集中第一行的第一列。忽略额外的列或行。
''' </summary>
''' <returns></returns>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Function ExecuteScalar() As Object Implements System.Data.IDbCommand.ExecuteScalar
Try
Me.Open()
DebugCommandText()
Dim obj As Object = Me.Command.ExecuteScalar
Return obj
Catch ex As Exception
Throw New Lily.core.DataProvider.DataProviderException(ex.Message, ex)
Finally
Me.Close()
End Try
End Function
''' -----------------------------------------------------------------------------
''' <summary>
''' 执行插入语句并返回自动增量的值.
''' </summary>
''' <returns></returns>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Function ExecuteIncrement() As Long Implements IDataProvider.ExecuteIncrement
'SCOPE_IDENTITY()
Try
Me.Open()
Me.CommandText = Me.CommandText & " " & " select SCOPE_IDENTITY()"
DebugCommandText()
Dim obj As Object = Me.Command.ExecuteScalar
Return obj
Catch ex As Exception
Throw New Lily.core.DataProvider.DataProviderException(ex.Message, ex)
Finally
Me.Close()
End Try
End Function
Public ReadOnly Property Parameters() As System.Data.IDataParameterCollection Implements System.Data.IDbCommand.Parameters
Get
Return Me.Command.Parameters
End Get
End Property
''' -----------------------------------------------------------------------------
''' <summary>
''' 在数据源上创建该命令的准备好的(或已编译的)版本。
''' </summary>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Sub Prepare() Implements System.Data.IDbCommand.Prepare
Me.Command.Prepare()
End Sub
''' -----------------------------------------------------------------------------
''' <summary>
''' 获取或设置在其中执行.NET Framework 数据提供程序的Command 对象的事务。
''' </summary>
''' <value></value>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Property Transaction() As System.Data.IDbTransaction Implements System.Data.IDbCommand.Transaction
Get
Return Me.Command.Transaction
End Get
Set(ByVal Value As System.Data.IDbTransaction)
Me.Command.Transaction = Value
End Set
End Property
''' -----------------------------------------------------------------------------
''' <summary>
''' 获取或设置命令结果在由DbDataAdapter 的Update 方法使用时如何应用于DataRow。
''' </summary>
''' <value></value>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Property UpdatedRowSource() As System.Data.UpdateRowSource Implements System.Data.IDbCommand.UpdatedRowSource
Get
Return Me.Command.UpdatedRowSource
End Get
Set(ByVal Value As System.Data.UpdateRowSource)
Me.Command.UpdatedRowSource = Value
End Set
End Property
Private IsDisposed As Boolean
''' -----------------------------------------------------------------------------
''' <summary>
''' 释放对象资源.
''' </summary>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Sub Dispose() Implements System.IDisposable.Dispose
If Not Me.IsDisposed Then
IsDisposed = True
If Not Me.md_Command Is Nothing Then Me.md_Command.Dispose()
If Not Me.md_Connection Is Nothing Then Me.md_Connection.Dispose()
If Not Me.md_Tran Is Nothing Then Me.md_Tran.Dispose()
Me.md_Command = Nothing
Me.md_Tran = Nothing
Me.md_Connection = Nothing
End If
End Sub
''' -----------------------------------------------------------------------------
''' <summary>
''' 返回或设置是否在执行完命令后自动关闭连接.
''' </summary>
''' <value></value>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public Property AutoCloseConnection() As Boolean Implements Core.DataProvider.IDataProvider.AutoCloseConnection
Get
Return Me.md_blnAutoCloseConnection
End Get
Set(ByVal Value As Boolean)
Me.md_blnAutoCloseConnection = Value
If Value Then
'关闭连接
Me.Close()
End If
End Set
End Property
''' -----------------------------------------------------------------------------
''' <summary>
''' 返回命令对象.
''' </summary>
''' <value></value>
''' <remarks>
''' </remarks>
''' <history>
''' [zqonline] 2006-10-20 Created
''' </history>
''' -----------------------------------------------------------------------------
Public ReadOnly Property Command() As System.Data.IDbCommand Implements Core.DataProvider.IDataProvider.Command
Get
Me.md_Command.Connection = Me.md_Connection
Return Me.md_Command
End Get
End Property
#End Region
#Region "私有方法"
Private Sub DebugCommandText()
If Not Me.Command Is Nothing Then
Lily.Core.Shared.DebugMessage.Invoke(Me.Command.CommandText)
End If
End Sub
#End Region
End Class
连接执行状态都是执行后就进行关闭,只有当使用事务或显示的指定不自动关闭连接时,需要手动关闭连接。其中方法DebugCommandText主要是用于显示或记录执行的语句。记录器需要外部提供。这里我是引用了组件Lily.Core.Dll.在后面的讲述,我们将进行介绍。此类的实现我就为系统提供了对数据库打交道的基石。
BS: 我在使用此类时,如果很频繁的对数据库进行打开和关闭操作。有时会出现连接池满的情况。由于我目前都是在WinForm下进行开发,所以只是针对WinForm进行设计和开发。
下一节准备开始讲实体。虽然这些代码是自己写的。不过没有进行过设计,现在写成文档居然比较陌生。目前为此我觉得在做信息系统的程序开发时最大的困难是类名,方法名,属性名的取名。