我可以使用LINQ过滤子项而不是嵌套for循环

时间:2018-02-22 12:33:18

标签: vb.net entity-framework linq

我希望能够查询设定数据并显示它和它的孩子。

我想查看所有父记录,但不是所有子记录。需要过滤子记录。

这是当前的情况:

Dim query = db.StockLocations.Where(Function(q) q.Id = 1).ToList()

For Each item As StockLocation In query
    For Each ls As LiveStock In item.LiveStocks.Where(Function(x) x.QtyKg > 0 AndAlso x.Issued = False)
        Console.WriteLine("Reel Id: " & ls.Id)
    Next
Next

Console.ReadLine()

我以为我可以在父母的孩子身上使用Linq.Any(),但它会返回每个孩子,而不是所需的过滤器孩子:

Dim linqquery = db.StockLocations.Where(Function(q) q.Id = 1 AndAlso q.LiveStocks.Any(Function(x) x.QtyKg > 0 AndAlso x.Issued = False)).ToList()

For Each item As StockLocation In linqquery
    For Each ls As LiveStock In item.LiveStocks
        Console.WriteLine("Reel Id: " & ls.Id)
    Next
Next

Console.ReadLine()

有没有办法从主查询中执行此操作,而不是在第二个for循环中单独查询子项?

更新 所以,根据Rahul Singh的回答,这看起来很奇怪。如果我同时使用这两个条件,我就没有结果。如果我只使用x.QtyKg > 0,那么确实会带来一些结果,但显然这并不合适。请参阅下面的新代码和输出:

Dim query = db.StockLocations.Where(Function(q) q.Id = 12).ToList()

Console.WriteLine("First query (Child filter in for loop)...")
For Each item As StockLocation In query
    Console.WriteLine("Record Count: " & item.LiveStocks.Where(Function(x) x.QtyKg > 0 AndAlso x.Issued = False).Count)
    For Each ls As LiveStock In item.LiveStocks.Where(Function(x) x.QtyKg > 0 AndAlso x.Issued = False)
        Console.WriteLine(ls.Id & " - " & ls.QtyKg & " - " & ls.Issued)
    Next
 Next

 Console.WriteLine("")
 Dim linqquery = db.StockLocations.Where(Function(q) q.Id = 12 AndAlso q.LiveStocks.All(Function(x) x.QtyKg > 0)).ToList()

 Console.WriteLine("Second query (q.LiveStocks.All(Function(x) x.QtyKg > 0))...")
 For Each item As StockLocation In linqquery
    Console.WriteLine("Record Count: " & item.LiveStocks.Count)
    For Each ls As LiveStock In item.LiveStocks
         Console.WriteLine(ls.Id & " - " & ls.QtyKg & " - " & ls.Issued)
    Next
 Next

 Console.WriteLine("")
 Dim linqquery1 = db.StockLocations.Where(Function(q) q.Id = 12 AndAlso q.LiveStocks.All(Function(x) x.QtyKg > 0 AndAlso x.Issued = False)).ToList()

 Console.WriteLine("Second query (q.LiveStocks.All(Function(x) x.QtyKg > 0 AndAlso x.Issued = False))...")
 For Each item As StockLocation In linqquery1
      Console.WriteLine("Record Count: " & item.LiveStocks.Count)
      For Each ls As LiveStock In item.LiveStocks
        Console.WriteLine(ls.Id & " - " & ls.QtyKg & " - " & ls.Issued)
      Next
 Next

输出(密钥:Id - QtyKg - 已发布): Console Output

1 个答案:

答案 0 :(得分:1)

您可以投影已过滤的父级,然后对子集合进行过滤,如下所示: -

Dim result = stocks.Where(Function(x) x.Id = 2).Select(Function(x)
      Dim filter = x.LiveStocks.Where(Function(z) z.Quantity > 0 AndAlso Not z.Issued)
      Return New Stock With {.Id = x.Id, .LiveStocks = filter.ToList()}
                                                       End Function)