在資料庫設計時,也許會有一些約定,說一下我自己的三點基本硬性規定: 1、所有欄位都為可空設定(主鍵、布爾類型欄位除外) 2、字元串類型不允許有前後空格(可能特殊情況時除外) 3、如果是空字元串,則應存儲Null(為了防止不同資料庫類型對字元串為空和NULL的不同對待) 第一點是設計時的事情,在這裡可 ...
在資料庫設計時,也許會有一些約定,說一下我自己的三點基本硬性規定:
1、所有欄位都為可空設定(主鍵、布爾類型欄位除外)
2、字元串類型不允許有前後空格(可能特殊情況時除外)
3、如果是空字元串,則應存儲Null(為了防止不同資料庫類型對字元串為空和NULL的不同對待)
第一點是設計時的事情,在這裡可以略過,而後兩點則是歸程式判斷處理的,也許細心的你發現了,第二點和第三點是銜接的。
接下來我們來看一下後兩點是如何實現的,以TextBox為例,我是這樣進行的:
'在驗證數據時進行
Me.txtRemark.Trim()
'在保存時進行
With info
If (Me.txtRemark.HasValue) Then
.Remark = Me.txtRemark.Text
Else
.Remark = Nothing
End If
End With
這段代碼並不難理解,不過需要說明的是,必填的欄位為了驗證是否有值Trim是得有的,而不必填的欄位實質上則只需要賦值的那一行,Trim和Null則可以交由底層SqlHelper里進行處理。
首先我們定義一個配置類來進行控制:
''' <summary>
''' Database configuration
''' </summary>
Friend NotInheritable Class Config
' Removes all occurrences of white space characters
Public Shared ReadOnly TrimString As Boolean = True
' translate the empty string to null
Public Shared ReadOnly EmptyStringToNull As Boolean = True
' translate the null boolean to false
Public Shared ReadOnly NullBooleanToFalse As Boolean = True
' translate the null value to dbnull value
Public Shared ReadOnly NullValueToDBNull As Boolean = True
End Class
前三項正是我們要實現的功能的開關,而最後一項NullValueToDBNull則需要另外說明一下了:
在實體類中,值類型我都是用Nullable(Of T)來存儲的,這當中就包含了Null的情況,而在傳遞至資料庫時,Null是作為預設值還是DBNull呢?這是不確定的,所以這個開關就是用於約定Null作為DBNull處理。
接下來就是對SqlHelper的改造了,需要改動的只有一個方法:PrepareCommand
''' <summary>
''' This method opens (if necessary) and assigns a connection, transaction, command type and parameters
''' to the provided command.
''' </summary>
''' <param name="command">the SqlCommand to be prepared</param>
''' <param name="connection">a valid SqlConnection, on which to execute this command</param>
''' <param name="transaction">a valid SqlTransaction, or 'null'</param>
''' <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
''' <param name="commandText">the stored procedure name or T-SQL command</param>
''' <param name="commandParameters">an array of SqlParameters to be associated with the command or 'null' if no parameters are required</param>
Private Shared Sub PrepareCommand(ByVal command As SqlCommand, _
ByVal connection As SqlConnection, _
ByVal transaction As SqlTransaction, _
ByVal commandType As CommandType, _
ByVal commandText As String, _
ByVal commandParameters() As SqlParameter)
'if the provided connection is not open, we will open it
If connection.State <> ConnectionState.Open Then
connection.Open()
End If
'associate the connection with the command
command.Connection = connection
'set the command text (stored procedure name or SQL statement)
command.CommandText = commandText
'if we were provided a transaction, assign it.
If Not (transaction Is Nothing) Then
command.Transaction = transaction
End If
'set the command type
command.CommandType = commandType
'attach the command parameters if they are provided
If Not (commandParameters Is Nothing) Then
For Each p As SqlParameter In commandParameters
If (p.Direction <> ParameterDirection.Output) Then
Select Case p.DbType
Case DbType.String, DbType.StringFixedLength, DbType.AnsiString, DbType.AnsiStringFixedLength
If (Not p.Value Is Nothing AndAlso Not p.Value Is DBNull.Value) Then
Dim str As String = p.Value.ToString()
If (Config.TrimString) Then
str = str.Trim()
End If
If (Config.EmptyStringToNull AndAlso str.Length = 0) Then
str = Nothing
End If
p.Value = str
End If
Case DbType.Boolean
If (Config.NullBooleanToFalse AndAlso p.Value Is Nothing) Then
p.Value = False
End If
End Select
If (Config.NullValueToDBNull AndAlso p.Value Is Nothing) Then
p.Value = DBNull.Value
End If
End If
command.Parameters.Add(p)
Next
End If
End Sub 'PrepareCommand
可以看到根據Parameter的DbType作了相應的處理,這樣處理後,非必填的欄位,就只以只用一句賦值語句,剩下的去空白字元和Null判斷就交由底層處理了,省心省力!~~~