文章出處

承接著上一篇, 這一篇主要以堆棧的方式來演示一下, db數據轉換到類中去的一個過程.

一、先看第一張圖

程序在運行到176行(上一篇貼出的代碼)的時候, 就會出現上圖中的第一個棧. 

那在此之前, Dapper又做了些什么呢? 拋開Dapper的這種OpCodes的實現方式來說, 我們自己用代碼去轉換, 實現思路如下:

1. 首先肯定是要獲取, 從db讀取出來的那么多列中, 有哪一些是需要轉換的吧, 如果是select * , 那會讀取出所有的列, 但是我本身并不需要那么多列, 而且, 我接收的類, 本身可能并沒有那么多的列, 所以, 首先確定有哪些列需要轉換, 以及這些列從db中讀取出來是什么類型的. 

2. 當確定好有效的列之后, 就可以獲取類中的構造函數, 已備創建類的時候使用. 在獲取構造函數的時候, 當然是越簡單的構造函數越好.(Dapper中會優先檢測標有ExplicitConstructor屬性的構造函數, 然后獲取構造函數的參數, 然后初始化參數), 然后就是把這個類new出來.

3. 到現在, 我們其實就已經能知道source data type 和 target property/feild type了, 既然已經兩邊的類型都已經知道, db數據已經準備好, target class也已經new好了, 就可以來實現轉換了, 根據類型的不同, 來使用不同的轉換. 值得一提的事, 如果 target class中, 含有自定義類的屬性或者字段, Dapper是不會繼續轉換的, 直接給了個null就了事了. 其實Dapper中, 也是可以實現此功能的, 這部分以后再說.

那么現在回到Dapper里來, 其實他做的工作也是這樣子的, 順序可能稍有不同, 1,2的順序是可調的. 只是他實現的方式稍有不同而已. 條條大路通羅馬, 目的地都是相同的, 不同的是途中的風景.

二、接著第二張圖

上圖中的第一個棧, 是執行完 181行 代碼之后, 出現的情況, 180行, 181代碼的意思, 其實就是把 reader[index]復制一份到 loc2中, 這個loc2就是前面(161行)聲明的, 類型為object的本地變量, 所以, 從堆棧的情況來看, 180行未執行前, 和181行執行完之后的堆棧是一樣的. 所以我就不畫了. 

在執行Unbox_Any之前, 是已經知道source type和target type了, 并且已經經過判斷, 是否能夠轉換, 然后再通過Unbox_Any來轉, Unbox是拆箱操作, Unbox_Any是拆箱成你需要的類型

上面這兩幅圖就是正常情況下(int, string, datetime, double等)的堆棧變化過程了, 應該還是比較能輔助理解的了.

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()