[.net MVC] Dapper動態接收、處理資料

有時候我們會有取資料需要Join 其他張表的情況,以前我的處理都是直接加欄位在ViewModel裡面

但其實有些時候可能就只會需要另一張表的一、兩個欄位,而且這一頁也就只用這一次

今天在Coding的時候與同事討論,我們決定用動態的方式來接收資料,不另外新增ViewModel Prop 

另外也有一種情況是Index時就已經有ViewModel 然後可以再把動態取得的這些 放在 ViewModel內
在Controller out 的部分就由ViewModel 傳回 以下方例子來看。原本out IEnumerable<dynamic> data 改寫到既有的ViewModel內
然後變成out VideModel 傳回

 

首先我們的 流程 就是

1.Controller 接收後 (前端Post後)
2.Service
3.Dal 取資料,取回IList<IDictionary<string,object>> 的資料包 
4.在Service 組成前端所需的樣子
5.從Controller 吐回前端
6.在前端定義好 Model(Prop與在Service新組成的Prop相同)
7.Post Success 後 取前端的Model 做邏輯運算

 

1.Controller 接收後 (前端Post後)

            var result = new
            {
                IsSuccess = tableCatalogPdfService.GetPdfData(out IEnumerable<dynamic> data, prjIdEncode),
                Content = data
            };
            
            return Json(result);

備註:因為需要遵循之前所說的所有方法都需要有boolean去做控制,以至於用out 來做return.

2.Service呼叫 Dal 部分

        public bool GetPdfData(out IEnumerable<dynamic> data, string prjIdEncode)
        {
            data = null;
            if (!tableCatalogPdfDal.GetPdfData(out IList<IDictionary<string, object>> listObject, prjIdEncode))
            {
                LogSet.LogError(string.Format("Invoke GetPdfData() error. Input: [prjId={0}]", prjId));
                return false;
            };
        }

3.Dal 取資料,取回IList<IDictionary<string,object>> 的資料包 

        public bool GetPdfData(out IList<IDictionary<string, object>> listObject,string prjId)
        {
            
            Debug.Assert(!string.IsNullOrWhiteSpace(prjId), "prjId不為空值");
            #填入 sql command

            #填入 parameter

            listObject = ExecuteQuery(sqlCommand, objParam);           
            return listObject.Count > 0 ? true : false;
        }

備註:這裡是用Dapper來取資料,而Dapper的ExecuteQuery吐出的就是IList<IDictionary<string,object>>的型別
當然也可以用Execute<object> 改用IList<object>來接,但就List內裝的Object必須要再轉IDiconary<stirng,object>
所以直接用IList<IDictionary<string,object>> 是最好的(當然還有就是直接用dynamic來接,但就是runtime的時候會再判斷、耗效能)

4.在Service 組成前端所需的樣子

        public bool GetPdfData(out IEnumerable<dynamic> data, string prjIdEncode)
        {
            data = null;
            #region 組成畫面要的物件
            data = listObject.Select((dataDetail, index) => new
            {
                //序號
                SeqNo = index + 1,
                //案件ID
                PrjID = dataDetail[nameof(PrjMain.PrjID).ToUpper()],
                //案件名稱
                PrjName = dataDetail[nameof(PrjMain.PrjName).ToUpper()],
                //內容型別
                ContentType = dataDetail[nameof(PrjContent.ContentType).ToUpper()],
                //內容
                Content = dataDetail[nameof(PrjContent.Content).ToUpper()]
            });
            #endregion
            return true;  
        }

備註:注意這邊data 一定要指定,out 相等於方法中必須回傳的值,所以一定要指定,另外Dapper會把SQL內的欄位轉出當成Dictionary的Key值
也因為這樣所以在組成物件的時候,組成大寫的樣子。

5.從Controller 吐回前端
6.在前端定義好 Model(Prop與在Service新組成的Prop相同)
7.Post Success 後 取前端的Model 做邏輯運算

這三個就不列出程式了

這次動態取資料複習了很久沒用的LINQ,