iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 2
4

在前期開發階段因為表格結構還在調整階段,或是不值得額外宣告類別輕量需求,使用Dapper dynamic Query可以節省下來回修改class屬性的時間。當表格穩定下來後使用POCO生成器快速生成Class轉成強型別維護。

為何Dapper可以如此方便,支援dynamic?

追溯Query方法源碼可以發現兩個重點

  1. 實體類別其實是DapperRow再隱性轉型為dynamic。
    20191003180501.png
  2. DapperRow繼承IDynamicMetaObjectProvider並且實作對應方法。

20191003044133.png

此段邏輯我這邊做一個簡化版本的Dapper dynamic Query讓讀者了解轉換邏輯 :

  1. 建立dynamic類別變數,實體類別是ExpandoObject
  2. 因為有繼承關係可以轉型為IDictionary<string, object>
  3. 使用DataReader使用GetName取得欄位名稱,藉由欄位index取得值,並將兩者分別添加進Dictionary當作key跟value。
  4. 因為ExpandoObject有實作IDynamicMetaObjectProvider介面可以轉換成dynamic
public static class DemoExtension
{
	public static IEnumerable<dynamic> Query(this IDbConnection cnn, string sql)
	{
		using (var command = cnn.CreateCommand())
		{
			command.CommandText = sql;
			using (var reader = command.ExecuteReader())
			{
				while (reader.Read())
				{
					yield return reader.CastToDynamic();
				}
			}
		}
	}
	
	private static dynamic CastToDynamic(this IDataReader reader)
	{
		dynamic e = new ExpandoObject();
		var d = e as IDictionary<string,object>;
		for (int i = 0; i < reader.FieldCount; i++)
			d.Add(reader.GetName(i),reader[i]);
		return e;
	}
}

20191003044145.png


上一篇
【深入Dapper.NET源碼】前言、安裝環境
下一篇
【深入Dapper.NET源碼】Dynamic Query 原理 Part2
系列文
🌊 進階學習 ADO.NET、Dapper、Entity Framework 30

尚未有邦友留言

立即登入留言