我有这个清单:
string[] countries = {
"USA",
"CANADA"
};
当我运行此查询时:
query = (from user in db where
user.Orders.Any(order => order.Price > 10 &&
countries.Contains(order.DestinationCountry)))
输出是将订单发送到" USA"的用户列表。 或"加拿大"。
但我希望将订单发送给" USA" 和" " CANADA"
我可以使用以下代码执行此操作,但我正在搜索纯粹的linq解决方案而没有任何 ForEach :
foreach (country in countries) {
query = (from user in query where
user.Orders.Any(order => order.Price > 10 &&
order.DestinationCountry == country));
}
数目:
一个。使用.Aggregate()
生成的查询就像For Each。
B中。where countries.All(c => user.Orders.Any(o => o.Price > 10 && o.DestinationCountry == c))
当国家列表中没有元素时(当我希望所有用户仅基于Price参数时),结果不正确,不考虑其他参数!
更新1:
我在发布之前尝试过 .All()而不是 .Contains(),它会返回0个用户。
更新2:
我已经更新了我的问题,使其更接近真正的问题。
让我们说国家不是唯一的参数。
更新3:
检查了一些答案并将结果添加到我的问题中。
答案 0 :(得分:3)
所以你想要一个用户列表,这样列表中的所有国家都出现在订单目的地集中?
逻辑上,那将是:
query = from user in db
where countries.All(c => user.Orders.Any(o => o.DestinationCountry == c))
select ...;
然而,我并不相信EF会做你想做的事情。我不清楚正确的SQL查询是从什么开始的 - 至少以简单的方式。
答案 1 :(得分:3)
query =
db.Users.Where(user =>
countries.All(country =>
user.Orders.Any(order =>
order.DestinationCountry == country)))
答案 2 :(得分:2)
你可以这样做:
query = (from user in db where
user.Orders
.Where(o => countries.Contains(o.DestinationCountry))
.GroupBy(o => o.DestinationCountry)
.Count() == countries.Count
);
我们的想法是只将订单发送到感兴趣的国家,然后按国家/地区分组,并检查组的数量是否等于国家数量。
答案 3 :(得分:1)
可以使用Enumerable.Aggregate
:
query = countries.Aggregate(query,
(q, c) =>
from user in q
where user.Orders.Any(order => order.DestinationCountry == c)
select user);
但实际上,这比你的foreach
循环更难理解,所以我就是这样。
请注意,虽然我引用了Enumerable
的成员,但Enumerable
的成员实际上正在建立一个IQueryable<User>
查询链,就像您的foreach
循环一样,所以这不会导致过滤移动到客户端。