一直以來都知道Dapper在做存取資料庫方面非常的簡單,只需要給予該SQL語法以及回傳的Model型別,就可以將對應的資料回傳並且轉換成List。
而其中Dapper還有一個最厲害的地方就是:不用預先宣告強型別,查詢資料表後就可以直接傳回 dynamic 的List。
例如:var list = cn.Query("SELECT Name,Class FROM Student").ToList();
該語法將傳回 List<dynamic>,因此不需要特別建立Model也可以將該資料回傳並作使用。
因此開始思考,如何透過dynamic動態生成物件?
今天就來介紹如何使用ExpandoObject動態建立欄位,並將資料回傳成 List<dynamic>吧!
ExpandoObject是在.Net Framework 4之後出現的一個類別 ,可以幫助我們為物件動態的加入或移除屬性成員。
其用法為:
dynamic data = new ExpandoObject();
data.Name = "Leo";
data.Sex= "Male";
我們需要搭配dynamic才能夠存取我們指定的Name,Sex欄位。
但是僅僅這樣寫,雖然可以自動幫我們建立Namx,Sex欄位,並給予值。但若是在欄位名稱未知的情況下想要動態建立Model,可就沒辦法了。
如上面所說,若需要將撈出來的SQL資料,根據其欄位建立Model並賦予值,那肯定無法做到。
但值得一提的是,由於ExpandoObject本身就實作了IDictionary<string, object>
,因此若是有必要我們也可以直接把它轉型成IDictionary<string, object>
來操作,讓該物件擁有Add以及Remove的方法,為物件動態的加入或移除屬性成員。
因此撰寫上我們會改為這樣的寫法:
var MyDynamic = new ExpandoObject() as IDictionary<string, Object>;
MyDynamic.Add("Name", "leo");
MyDynamic.Add("Sex", "Male");
透過這樣的方式,將我們的屬性利用字串的方式Add至MyDynamic物件中,這樣我們就能存取Name以及Sex的值了。
因此若想像Dapper一樣回傳成List<dynamic>的集合資料的話,最終的版本可以寫成這樣:
// 本範例使用SqlDataReader做資料庫存取
List<dynamic> list = new List<dynamic>();
SqlCommand command = new SqlCommand(sql, connection);
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
IDictionary<String, Object> MyDynamic = new ExpandoObject() as IDictionary<string, Object>;
for (int i = 0; i < reader.FieldCount;i++) // 透過FieldCount 取得該列資料中的所有欄位數目
{
MyDynamic.Add(reader.GetName(i), reader[i]); //動態將SQL存取到的欄位以及Value 放入MyDynamic中
}
list.Add(MyDynamic);
}
透過這樣的方式,我們就可以像Dapper一樣,不需要建立Model類別,也能輕鬆的將資料存取回來,並轉換為List做後續操作。
另外,仔細追查Dapper的原始碼,我們也可以發現到,Dapper之所以能做到不需要指定Model型別,也能回傳dynamic的List的原因,也是透過實作了IDictionary<string, object>
。
因此在dapper中,外表看似是dynamic其實骨子裡是DapperRow的型別。
以上文章敘述如有錯誤及觀念不正確,請不吝嗇指教:)
有任何家教、案子 或技術相關問題 請都歡迎聯繫我