iT邦幫忙

DAY 19
3

OpenAccess ORM for Oracle 實戰演練系列 第 15

OpenAccess ORM for Oracle 實戰演練 Day 19

建立OpenAccess ORM的監聽器
前一篇文章,我們透過設定物件容器的 Log 屬性來取得真正執行的 Sql 語法,但是 Log 屬性限制必須使用 TextWriter 物件,本篇文章就用另一種方式,可以讓我們自由設計要記錄 Sql 語法的方式。
OpenAccessContext.Log 屬性必須使用 System.IO.TextWriter 型別之物件,來收集真正執行的 Sql 語法,但是有些環境下,我們會希望自訂收集 Sql 語法的方式,本篇文章範例,我們就用一個 StringBuilder 物件做為收集體,然後呼叫端就可以透過 StringBuilder.ToString() 取得記錄下來的資料。

首先,我們延續上一篇的 ProductMgmt 類別,做點小修改,以下僅列出調整的部分:

Public Class ProductsMgmt
    Private cxt As SecondModel
    Private output As IO.StringWriter
    Private tracer As MyNorthwindTraceListener
    Public Sub New()
        cxt = New SecondModel()
        output = New IO.StringWriter()
        cxt.Log = output
        tracer = New MyNorthwindTraceListener(New Text.StringBuilder())
    End Sub

    Public Function GetLogString() As String
        If tracer IsNot Nothing Then
            Return tracer.GetLogString()
        Else
            Return Nothing
        End If
    End Function

    ......
    ......
    ......

End Class

主要是在建構式,我們多加一個建立 MyNorthwindTraceListener 物件的程式,另外加入一個 GetLogString() 函式,回傳 tracer.ToString() 結果。

接下來我們建立 MyNorthwindTraceListener 類別:

Imports System.Threading
Imports Telerik.OpenAccess.Diagnostics
Imports System.Text

Public Class MyNorthwindTraceListener
    Inherits TraceListener
    Private id As Integer
    Private count As Integer
    Private _sb As StringBuilder
    Private myThread As Thread

    Public Sub New(ByVal sb As StringBuilder)
        MyBase.New("Northwind Trace Listener")
        Me.myThread = Thread.CurrentThread
        Me._sb = sb
        Me.count = 0
        TraceAdapter.Instance.Level = "4"
        Me.id = TraceAdapter.Instance.Listeners.Add(Me)
    End Sub

    Public Overloads Overrides Sub Write(ByVal message As String)
        Me.WriteLine(message)
    End Sub

    Public Overloads Overrides Sub WriteLine(ByVal message As String)
        If Object.ReferenceEquals(Me.myThread, Thread.CurrentThread) = False Then
            Return
        End If
        If message.StartsWith("driver.stat.exec") Then
            count += 1
            Dim index As Integer
            If message.IndexOf("SELECT") >= 0 Then
                index = message.IndexOf("SELECT")
            ElseIf message.IndexOf("INSERT") >= 0 Then
                index = message.IndexOf("INSERT")
            ElseIf message.IndexOf("UPDATE") >= 0 Then
                index = message.IndexOf("UPDATE")
            ElseIf message.IndexOf("DELETE") >= 0 Then
                index = message.IndexOf("DELETE")
            End If
            _sb.AppendLine(String.Format("{0}: {1}" & vbCrLf, count, message.Substring(index)))
        End If
    End Sub

    Friend Sub Reset()
        Me._sb = New StringBuilder()
        Me.count = 0
    End Sub

    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        _sb.AppendLine(Me.count.ToString() & " quires executed")
        MyBase.Dispose(disposing)
    End Sub

    Public Function GetLogString() As String
        Return _sb.ToString()
    End Function
End Class

上述程式碼最重要的部分,就是要繼承 TraceListener 類別,並在建構子中,把自己加入 Listeners 集合中,若少了這個動作,就不會記錄 Log 了。建構式的傳入參數,就是用來收集資料的物件,在此我們使用 StringBuiler。

WirteLine() 則是把 OpenAccess ORM 記錄下來的訊息物件(message)做適當的處理(因為 message 中會包含許多 ORM 架構之訊息資料,我們在此只擷取 Sql 語法),然後調用 StringBuiler.AppendLine() 把處理的結果儲存下來。

最後我們建立一個 GetLogString() 函式,回傳 StringBuiler.ToString() 的結果。

現在我們延用上一篇的測試案例(純脆是求快而已,正常應該要再加一個測試案例):

<TestMethod()> _
Public Sub TraceSQLStatementsTest()
    Dim target As ProductsMgmt = New ProductsMgmt()
    Dim actual As IList(Of Products)
    actual = target.GetGiantProducts
    Assert.IsTrue(actual.Any)
    Assert.IsNotNull(target.TraceSQLStatements())
    Assert.IsNotNull(target.GetLogString())
End Sub

測試通過後,我們一樣延用前一篇的 ShowTraceSQLStatements.aspx 頁面,但是在程式中把原本輸出的地方調整一下:

Private Sub DataBinding(ByVal bo As ProductsMgmt)
    gvList.DataSource = bo.GetGiantProducts()
    gvList.DataBind()
    'lblSQL.Text = bo.TraceSQLStatements()
    lblSQL.Text = bo.GetLogString().Replace(vbCrLf, "<br />")
End Sub

執行結果如下:

上述 Gif 圖檔的直接連結:http://i.minus.com/iopqGlRKD2QOx.Gif


上一篇
OpenAccess ORM for Oracle 實戰演練 Day 18
下一篇
OpenAccess ORM for Oracle 實戰演練 Day 20
系列文
OpenAccess ORM for Oracle 實戰演練26

尚未有邦友留言

立即登入留言