我有一个场景如下嵌套
--Orders (List)
----Products (List)
------Manufacturers (List)
FIELDS
-Name
-Address
-City
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我需要执行查询,该查询将过滤制造商城市并返回Orders, Products & only matching city manufacturers
我尝试提出以下查询,但是即使 city 与Manufacturers不匹配,我也得到了所有产品列表。
var filteredOrders = from o in Orders
from t in o.Products
where t.Manufacturers.Any(v => v.City == "Hartford")
select o;
Run Code Online (Sandbox Code Playgroud)
或者,即使我从select o“选择 t.Manufacturers”更改为“选择 t.Manufacturers”,我也会获得所有制造商列表,无论城市过滤器如何。
幸运的是,我得到了符合我的场景的 W3school SQL 示例。 https://www.w3schools.com/sql/trysql.asp?filename=trysql_op_or
SQL查询:
SELECT o.OrderId, p.ProductName, s.*
FROM [Orders] o
JOIN OrderDetails od ON o.OrderId = od.OrderId AND o.orderId = 10248
JOIN Products p ON od.ProductId = p.ProductId
JOIN Suppliers s ON p.SupplierId = s.SupplierId and s.City ='Singapore'
Run Code Online (Sandbox Code Playgroud)
我会将所有内容展平,然后仅过滤您想要的城市:
class Manufacturer
{
public string Name;
public string Address;
public string City;
}
class Product
{
public Manufacturer[] Manufacturers;
}
class Order
{
public Product[] Products;
}
static void Main(string[] args)
{
var cities = new string[] { "a", "b" };
Order[] orders = null;
orders.SelectMany(o => o.Products.SelectMany(p => p.Manufacturers.Select(m => new { o, p, m })))
.Where(g => cities.Contains(g.m.City))
.ToList();
}
Run Code Online (Sandbox Code Playgroud)
或者,如果你想返回new Order s (因为它们有不同的Products,它必须指向新分配的Object)你可以这样:
var newOrders = orders.Select(o => new Order()
{
Products = o.Products
.Select(p => new Product()
{
Manufacturers = p.Manufacturers.Where(m => cities.Contains(m.City)).ToArray()
})
.Where(m => m.Manufacturers.Length > 0).ToArray()
}).Where(p => p.Products.Length > 0).ToArray();
Run Code Online (Sandbox Code Playgroud)