Quantcast
Channel: 黑暗執行緒
Viewing all articles
Browse latest Browse all 2311

由 Dapper 傳回 dynamic 物件取得欄位清單

$
0
0

不用預先宣告強型別,查詢資料表後直接傳回 dynamic 是 Dapper的強項,例如:var list = cn.Query("SELECT Col1,Col2 FROM T).ToList(); 將傳回 List<dynamic>,用 list.Fisrt().Col1 就能讀取欄位內容,簡潔又方便。

最近有個花式應用,想用通用函式接收 Dapper 查詢結果,自動列舉其中包含屬性(資料庫欄位)。一開始依循 System.Refelction 思維,想說用 GetType().GetProperties() 就可以搞定,不料踢到鐵板,Dapper 傳回的 dynamic 物件 .GetType() 結果為 null:

進一步追查,Dapper 傳回的 dynamic 骨子裡其實是個 DapperRow 型別,特別的是它實做了 IDictionary<string, object> 介面:

還記得既然要動態就動個痛快 - ExpandoObject介紹過 IDictionary<string, object> 的妙用,既然 DapperRow 是個 IDictionary<string, object> 一切好辦,轉型後用 .Keys 取回屬性清單,接下來就簡單了。

staticvoid Main(string[] args)
        {
string sql = @"
SELECT 1 AS ColNum, SYSDATE AS ColDate, 'HELLO' AS ColString FROM DUAL UNION
SELECT 2 AS ColNum, SYSDATE AS ColDate, 'WORLD' AS ColString FROM DUAL
";
using (var cn = new OracleConnection(cs))
            {
                var res = cn.Query(sql);
                StringBuilder sb = null;
foreach (dynamic rec in res)
                {
                    var d = rec as IDictionary<string, object>;
if (sb == null)
                    {
                        sb = new StringBuilder(string.Join("\t", d.Keys.ToArray()));
                        sb.AppendLine();
                    }
                    sb.AppendLine(string.Join("\t",
                        d.Keys.Select(n => 
                            d[n] == null ? string.Empty : d[n].ToString()).ToArray()));
                }
                Console.WriteLine(sb.ToString());
 
                Console.Read();
            }
        }
 

經實測可成功列舉欄位名稱及內容:

COLNUM  COLDATE COLSTRING
1       2017/3/22 下午 09:07:30 HELLO
2       2017/3/22 下午 09:07:30 WORLD

最後,回到 DapperRow.GetType() 傳回 null 的謎團上,照理來說,GetType() 源自 Object 物件,查過 DapperRow 的原始碼並沒有覆寫 GetType(),想不出傳回 null 的理由。於是把問題丟上 stackoverflow,很快就有高手出面解惑,原來 DapperRow 實做了 DynamicMetaObject,攔截所有 dynamic 形式的成員存取,只要遇到非欄位名稱就傳回 null,因此不只 GetType(),呼叫 AsEnumerable() 也會傳回 null,所有謎團都解開了,結案!


Viewing all articles
Browse latest Browse all 2311

Trending Articles