SELECT cocode, arbook, batchdate, batchno,count(*)
FROM arpendingbill
WHERE cocode = 'TGIP' AND arbook = 'NEWAR'
GROUP BY cocode, arbook, batchdate, batchno
โดยให้นำข้อมูลไปใส่ Class ชื่อ ARPendingBatch เขียนเป็น LINQ ดังนี้ครับ
Dim b = From pb In dc.ARPendingBills _
Where pb.COCode = coCode AndAlso pb.ARBook = arBook _
Group By key = New With {pb.COCode, pb.ARBook, pb.BatchDate, pb.BatchNo} _
Into pbGroup = Group _
Select New ARPendingBatch With {.ARBook = key.ARBook, _
.CoCode = key.COCode, .BatchDate = key.BatchDate, _
.BatchNo = key.BatchNo, .BillCount = pbGroup.Count( _
Function(c) c.BatchDate = key.BatchDate AndAlso _
c.BatchNo = key.BatchNo)}
พอลอง debug เพื่อดู SQLCommand ที่มันสร้างขึ้นมาได้แบบนี้ครับ
SELECT ( SELECT COUNT(*) FROM [dbo].[ARPendingBill] AS [t2] WHERE ([t2].[BatchDate] = [t1].[BatchDate]) AND ([t2].[BatchNo] = [t1].[BatchNo]) AND ([t1].[COCode] = [t2].[COCode]) AND ([t1].[ARBook] = [t2].[ARBook]) AND ([t1].[BatchDate] = [t2].[BatchDate]) AND ([t1].[BatchNo] = [t2].[BatchNo]) AND ([t2].[COCode] = @p0) AND ([t2].[ARBook] = @p1) ) AS [BillCount], [t1].[BatchDate], [t1].[BatchNo], [t1].[ARBook], [t1].[COCode] AS [CoCode] FROM ( SELECT [t0].[COCode], [t0].[ARBook], [t0].[BatchDate], [t0].[BatchNo] FROM [dbo].[ARPendingBill] AS [t0] WHERE ([t0].[COCode] = @p0) AND ([t0].[ARBook] = @p1) GROUP BY [t0].[COCode], [t0].[ARBook], [t0].[BatchDate], [t0].[BatchNo] ) AS [t1]
รู้สึกว่ามันช่างเข้าใจยากพิกล ส่วนหนึ่งเป็นเพราะยังไม่ชินด้วยครับ และควรจะต้องไปจัด Layout ใหม่ให้อ่านง่ายๆก่อน แต่ผลลัพท์ได้ออกมาเหมือนกัน
ลองเขียนโดยใช้ Lambda Expression ครับ
Dim b = dc.ARPendingBills.Where( _
Function(a) a.COCode = coCode AndAlso a.ARBook = arBook).GroupBy( _
Function(g) New With {.coCode = g.COCode, .arBook = g.ARBook, _
.batchDate = g.BatchDate, .batchNo = g.BatchNo}).Select( _
Function(c) New ARPendingBatch With {.ARBook = c.Key.arBook, _
.CoCode = c.Key.coCode, .BatchDate = c.Key.batchDate, _
.BatchNo = c.Key.batchNo, .BillCount = c.Count( _
Function(k) k.BatchDate = c.Key.batchDate AndAlso _
k.BatchNo = c.Key.batchNo)})
ได้ผลลัพท์เหมือนกันครับ (ก็แหงละ ลอง debug ดู SQLCommand ก็เหมือนกับที่เขียนด้านบน)
รู้สึกขัดใจกับ SQLCommand ที่ Linq To SQL สร้างให้ ดังนั้นเลยเปลี่ยนมา ExecuteQuery ตรงๆแทน
Dim b = dc.ExecuteQuery(Of ARPendingBatch)( _
"SELECT cocode, arbook, batchdate, batchno, " & _
"BillCount=count(billRecId) " & _
"FROM arpendingbill & _
"WHERE cocode = '" & coCode & "' and arbook = '" & arBook & "' " & _
"GROUP BY cocode, arbook, batchdate, batchno")
มันไม่ Typed Save ครับ แต่ก็มีข้อดีคือ ผมไม่ต้องใช้เวลาเป็นชั่วโมงในการลองเขียน LINQ To SQl แล้ว debug ได้ SQLCommand ที่อ่านยาก และก็ต้อง Test เยอะเพื่อความมั่นใจ ดังนั้นช่วงนี้ถ้าเจอกรณีแบบนี้ก็จะใช้ ExecuteQuery ไปก่อน แล้วพอมีเวลาหัดให้คล่องๆแล้วค่อยกลับมาแก้ครับ (แต่มันก็อ่านยากเหมือนกันนะ programmer ที่ต้องมาแก้โค้ดนี้ภายหลัง ไม่แน่ใจว่าจะชอบแบบไหน ดังนั้นผมเลย Comment เก็บไว้ทั้ง 3 แบบเลย)
ว่าแต่โค้ด Linq To SQL ด้านบน สามารถเขียนได้ง่ายกว่านี้มั๊ยนะ
๓ ความคิดเห็น:
แนะนำตัวช่วยเขียน linq
1. http://www.linqpad.net/
2. http://code.msdn.microsoft.com/vlinq/Release/ProjectReleases.aspx?ReleaseId=810
SELECT cocode, arbook, batchdate, batchno,count(*)
FROM arpendingbill
WHERE cocode = 'TGIP' AND arbook = 'NEWAR'
GROUP BY cocode, arbook, batchdate, batchno
สั้นๆๆได้ ดังนี้ครับ
dim q = From pb In dc.ARPendingBills _
Where pb.COCode = coCode AndAlso pb.ARBook = arBook _
Group pb.cocode, pb.arbook, pb.batchdate, pb.batchno By _
pb.cocode, pb.arbook, pb.batchdate, pb.batchno into Group
Select Group.Count() , cocode, arbook, batchdate, batchno
ขอบคุณคุณ Tor ครับ เดี๋ยวจะลองใช้ดู
ส่วนคุณเด็กศรีราชา ผมลองแล้วมัน error ครับ ตรง
Group pb.cocode, pb.arbook
แต่ก็ขอบคุณครับ เดี๋ยวจะลองอีกที
แสดงความคิดเห็น