使用Linq Left join 兩個關聯資料表後,再使用Lambda實現Row_Number,Partition by
進而實現在EntityFrameWork下做出重複資料中各群組的特定一筆資料
最近開始玩EntityFrameWork,把一些SQL Command改掉感覺真舒服
但是碰到了一個難題 只好各個擊破
要實現三件事情
1.Left Join
2.Partition by
3.Row_Number()
總之圖表長這樣,Contra_Renew紀錄每個合約資料(中文Table見怪不怪 ...)的續約紀錄
PrimaryKey= 合約資料.No
ForeignKey=CONTRA_RENEW.ContraCorreCode
ForeignKey=CONTRA_RENEW.ContraCorreCode
1.Left Join
Public Function LeftJoinList(QueryValue As String)
Using Context As New MerchantDB
Dim getContra = (From data In Context.合約資料
From renewData In Context.CONTRA_RENEW.Where(Function(r) r.ContraCorreCode = data.No).DefaultIfEmpty
Where data.CustName = QueryValue
Select New With {
.col1 = data.col1,
.col2 = data.col2,
.col3 = data.col3,
.col4 = data.col4}).ToList
Return getContra
End Using
End Function
Linq的Join比較繁複一點 思考邏輯比較不同,前輩保哥在幾年有寫過相關文章
2.Row_Number / Partition by
Public Function LeftJoinList(QueryValue As String)
Using Context As New MerchantDB
Dim getContra = (From data In Context.合約資料
From renewData In Context.CONTRA_RENEW.Where(Function(r) r.ContraCorreCode = data.No).DefaultIfEmpty
Where data.CustName = QueryValue
Select New With {
.col1 = data.col1,
.col2 = data.col2,
.col3 = data.col3,
.col4 = data.col4}).ToList
Dim PartitionByContra = (getContra.GroupBy(Function(gb) gb.ContraNo).Select(Function(G) New With{Key .group = G,Key .Count = G.count()}).
SelectMany(Function(sm) sm.group.OrderByDecending(Function(obd) obd.ContraIniDate).
Zip(Enumerable.Range(1,sm.Count),Function(J,I) New With {Key .OrderNo = I,J.col1,J.col2,J.col3,J.col4,J.col5})).
Where(Function(Final) Final.OrderNo = 1)).ToList
Return PartitionByContra
End Using
End Function
我們直接從LeftJoinList加入另一個Lambda,從Lambda裡可以看到我做了幾件事情
1.先透過ContraNo這欄位,使用GroupBy來分類
2.在SelectMany中,我先將第一個GroupBy後的群組進行排序(因為我要的是最新的合約續約起始/到期日,可以看到我是對ContraIniDate的排序是Decending),再對sm的Count進行查詢
3.使用Zip將Sm.Count逐筆放到新的序列中,最後使用Where設定條件,此時資料已經明確分為各群組,且各群組內的元素皆有排序編號,要找最新的續約日期就很簡單了
ZIP資料解說這邊看
C#版本這裡看(StockOverFlow)
單純筆記,皆為非正規作法,旁門左道,胡搞瞎搞。