有時候我們會有取資料需要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,