如何在 vb.net 中使用 Linq groupby 以及带有日期条件的 where

问题描述 投票:0回答:1

我正在尝试在 vb.net 中使用 Linq groupby 和 where 以及日期条件

请指导我。

PIQ是总购买数量

SIQ是总销量

BLC是总购买量减去总销售量

谢谢

Public Class Form3
    Private Purchase, Sales As New List(Of Invoice)
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        LoadData()
    End Sub
    Private PurchaseDetails,SalesDetails As New List(Of Detail)
    Private Function CreateConnection() As String
        Return ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\TRIAL2.accdb;Persist Security Info=False;")
    End Function
Private Sub LoadData()
        Using Connection = New OleDbConnection(CreateConnection())
 Purchase = CType(Connection.Query(Of Invoice)("SELECT * FROM PURCHASE"), List(Of Invoice))
            PurchaseDetails = CType(Connection.Query(Of Detail)("SELECT * FROM PURCHASEDETAILS"), List(Of Detail))
 Sales = CType(Connection.Query(Of Invoice)("SELECT * FROM SALES"), List(Of Invoice))
            SalesDetails = CType(Connection.Query(Of Detail)("SELECT * FROM SALESDETAILS"), List(Of Detail))
End Using
        Dim ps = From p In Purchase
                 Where p.DATEINVO >= CDate("01/01/2024")
                 From pd In PurchaseDetails
                 Select
             pd.ITEM,
             PIQ = pd.QTY,
             SIQ = 0,
             BLC = pd.QTY
                 Order By ITEM
        Dim ss = From s In Sales
                 Where s.DATEINVO >= CDate("01/01/2024")
                 From sd In SalesDetails
                 Select
            sd.ITEM,
            PIQ = 0,
            SIQ = sd.QTY,
            BLC = -sd.QTY
                 Order By ITEM
 Dim Card_temp = ps.Union(ss).OrderBy(Function(w) w.ITEM)
 Dim Card As New List(Of ItemCards3)
        Dim RunningBalance As Integer = 0
        For Each ct In Card_temp
            Dim sc As New ItemCards3
            With sc
                .ITEM = ct.ITEM
                .PIQ = ct.PIQ
                .SIQ = ct.SIQ
                .BLC = RunningBalance + ct.BLC
                RunningBalance = .BLC
            End With
            Card.Add(sc)
        Next
        DataGridView1.DataSource = Card
    End Sub

End Class
Public Class Invoice
    Property INVONO() As String
    Property DATEINVO() As Date
    Property CUSTCODE() As String
End Class

Public Class Detail
    Public Property INVONO() As String
    Public Property NOD() As Integer
    Public Property ITEM() As String
    Public Property QTY() As Integer
End Class
Public Class ItemCards3
    Public Property ITEM() As String
    Public Property PIQ As Integer
    Public Property SIQ As Integer
    Public Property BLC As Integer
End Class

桌子

PURCHASE

伊沃诺 日期输入 海关代码
PI1000 23 年 1 月 25 日 001
PI1001 23 年 1 月 29 日 002
PI1002 24 年 1 月 29 日 003
PI0003 24 年 1 月 30 日 004

桌子

PURCHASEDETAILS

伊沃诺 诺德 项目 数量
PI1000 1 测试1000 10
PI1000 2 测试2000 20
PI1001 1 测试3000 15
PI1002 1 测试1000 20
PI1003 1 测试1000 15

桌子

SALES

伊沃诺 日期输入 海关代码
SI1000 23 年 1 月 25 日 001
SI1001 23 年 1 月 29 日 002
SI1002 24 年 1 月 29 日 005
SI1003 24 年 1 月 30 日 006
SI1004 24 年 1 月 29 日 004
SI1005 24 年 1 月 30 日 003

桌子

SALESDETAILS

伊沃诺 诺德 项目 数量
SI1000 1 测试1000 10
SI1000 2 测试2000 20
SI1001 1 测试8000 35
SI1002 1 测试1000 27
SI1003 1 测试1000 15
SI1004 1 测试2000 2
SI1005 1 测试2000 2

上面代码的结果

项目 PIQ SIQ BLC
测试1000 15 0 15
测试1000 10 0 25
测试1000 20 0 45
测试1000 0 10 35
测试1000 0 27 8
测试1000 0 15 -7
测试2000 20 0 13
测试2000 0 20 -7
测试2000 0 2 -9
测试3000 15 0 6
测试8000 0 35 -29

想要的结果

项目 PIQ SIQ BLC
测试1000 35 42 -7
测试2000 4 -4
vb.net linq group-by dapper
1个回答
0
投票

我看到的第一个问题是您的 Purchase/PurchaseDetails 查询引用了两个表,但没有提供联接条件。这将导致交叉连接,其中每个购买行都连接到每个购买详细信息行。这同样适用于 Sales/SalesDetails 查询。

我相信可以使用以下

Join ... On ...
LINQ 语法来纠正这个问题。

Dim ps = From p In Purchase
         Where p.DATEINVO >= CDate("01/01/2024")
         Join pd In PurchaseDetails On pd.INVONO = p.INVONO
         Select
             pd.ITEM,
             PIQ = pd.QTY,
             SIQ = 0,
             BLC = pd.QTY
         Order By ITEM
Dim ss = From s In Sales
         Where s.DATEINVO >= CDate("01/01/2024")
         Join sd In SalesDetails On sd.INVONO = s.INVONO
         Select
             sd.ITEM,
             PIQ = 0,
             SIQ = sd.QTY,
             BLC = -sd.QTY
         Order By ITEM

定义这两个查询后,您可以使用

.Union()
.GroupBy()
.Select()
.Sum()
的组合来组合、分组并计算结果总和。在
.Select()
中,分组
ITEM
值通过分组
.Key
属性访问,而其他值则使用
.Sum()
计算以迭代每个分组的成员。

结果会是这样的:

Dim Card_temp = ps.Union(ss) _
    .GroupBy(Function(w) w.ITEM) _
    .Select(Function(g) New ItemCards3 With {
        .ITEM = g.Key,
        .PIQ = g.Sum(Function(i) i.PIQ),
        .SIQ = g.Sum(Function(i) i.SIQ),
        .BLC = g.Sum(Function(i) i.BLC)
    }) _
    .OrderBy(Function(ic) ic.ITEM) _
    .ToList()

Dim Card_temp = (From w In ps.Union(ss)
                 Group By w.ITEM Into Group
                 Select New ItemCards3 With {
                     .ITEM = ITEM,
                     .PIQ = Group.Sum(Function(i) i.PIQ),
                     .SIQ = Group.Sum(Function(i) i.SIQ),
                     .BLC = Group.Sum(Function(i) i.BLC)
                 }
                 Order By ITEM).ToList()

.OrderBy()
.ToList()
出席以整理结果。

注意:我是一名C#程序员,不是VB程序员,所以我用C#准备了上述代码片段,并借助翻译工具翻译为VB。不确定我的语法是否完全正确 - 特别是对于必需的与可选的行延续字符

© www.soinside.com 2019 - 2024. All rights reserved.