Linq where子句混淆
Linq where clause confusion
大家好!
我已经为我的自动化测试编写了一个查询,但执行起来花费的时间太长,而且我不确定如何有效地优化它,因为我是 Linq where 子句的新手。
有人可以帮我解决这个问题吗?
var order = OrderRepositoryX.GetOrderByStatus(OrderStatusType.Dispatched, 4000)
.Where(x => x.siteId == 1 || x.siteId == 10 || x.siteId == 8 || x.siteId == 16 || x.siteId == 26 || x.siteId == 27)
.Where(x =>
{
var totalPrice = OrderRepository.GetOrderById(shared_parameters.testConfiguration, x.orderId).TotalPrice;
if (totalPrice < 500)
return false;
return true;
})
.Where(x =>
{
var cnt = ReturnOrderRepositoryX.CheckReturnOrderExists(x.orderId);
if (cnt > 0)
return false;
return true;
})
.Where(x =>
{
var cnt = OrderRepositoryX.CheckActiveOrderJobDetailsByOrderId(x.orderId);
if (cnt > 0)
return false;
return true;
})
.FirstOrDefault();
这里最大的代码味道是您在 Where
子句中调用其他存储库(假设存储库实际访问数据库)这实际上意味着您正在为每个查询项目访问数据库。假设 OrderRepositoryX.GetOrderByStatus(OrderStatusType.Dispatched, 4000)
和第一个 Where
将产生 1000 个项目,只有第二个 Where
子句将导致对数据库的 1000 个查询(并且您在后续 Where
s)。所有这一切只得到一件物品(即 FirstOrDefault
)。
通常的方法是避免在循环中调用数据库(Where
在这里基本上是这样做的)并重写这样的代码,因此只对数据库执行单个 SQL 查询,只返回需要的和在数据库端执行所有过滤。
请试试这个
避免过多的 where 子句。它得到一个结果,然后对整个集合应用另一个检查。
var order = OrderRepositoryX.GetOrderByStatus(OrderStatusType.Dispatched, 4000)
.FirstOrDefault(x => x.siteId == 1 || x.siteId == 10 || x.siteId == 8 || x.siteId == 16 ||
x.siteId == 26 || x.siteId == 27) &&
(x =>
{
var totalPrice = OrderRepository.GetOrderById(shared_parameters.testConfiguration, x.orderId)
.TotalPrice;
return totalPrice >= 500;
})
&& (x =>
{
var cnt = ReturnOrderRepositoryX.CheckReturnOrderExists(x.orderId);
return cnt <= 0;
})
&& (x =>
{
var cnt = OrderRepositoryX.CheckActiveOrderJobDetailsByOrderId(x.orderId);
return cnt <= 0;
});
大家好!
我已经为我的自动化测试编写了一个查询,但执行起来花费的时间太长,而且我不确定如何有效地优化它,因为我是 Linq where 子句的新手。
有人可以帮我解决这个问题吗?
var order = OrderRepositoryX.GetOrderByStatus(OrderStatusType.Dispatched, 4000)
.Where(x => x.siteId == 1 || x.siteId == 10 || x.siteId == 8 || x.siteId == 16 || x.siteId == 26 || x.siteId == 27)
.Where(x =>
{
var totalPrice = OrderRepository.GetOrderById(shared_parameters.testConfiguration, x.orderId).TotalPrice;
if (totalPrice < 500)
return false;
return true;
})
.Where(x =>
{
var cnt = ReturnOrderRepositoryX.CheckReturnOrderExists(x.orderId);
if (cnt > 0)
return false;
return true;
})
.Where(x =>
{
var cnt = OrderRepositoryX.CheckActiveOrderJobDetailsByOrderId(x.orderId);
if (cnt > 0)
return false;
return true;
})
.FirstOrDefault();
这里最大的代码味道是您在 Where
子句中调用其他存储库(假设存储库实际访问数据库)这实际上意味着您正在为每个查询项目访问数据库。假设 OrderRepositoryX.GetOrderByStatus(OrderStatusType.Dispatched, 4000)
和第一个 Where
将产生 1000 个项目,只有第二个 Where
子句将导致对数据库的 1000 个查询(并且您在后续 Where
s)。所有这一切只得到一件物品(即 FirstOrDefault
)。
通常的方法是避免在循环中调用数据库(Where
在这里基本上是这样做的)并重写这样的代码,因此只对数据库执行单个 SQL 查询,只返回需要的和在数据库端执行所有过滤。
请试试这个 避免过多的 where 子句。它得到一个结果,然后对整个集合应用另一个检查。
var order = OrderRepositoryX.GetOrderByStatus(OrderStatusType.Dispatched, 4000)
.FirstOrDefault(x => x.siteId == 1 || x.siteId == 10 || x.siteId == 8 || x.siteId == 16 ||
x.siteId == 26 || x.siteId == 27) &&
(x =>
{
var totalPrice = OrderRepository.GetOrderById(shared_parameters.testConfiguration, x.orderId)
.TotalPrice;
return totalPrice >= 500;
})
&& (x =>
{
var cnt = ReturnOrderRepositoryX.CheckReturnOrderExists(x.orderId);
return cnt <= 0;
})
&& (x =>
{
var cnt = OrderRepositoryX.CheckActiveOrderJobDetailsByOrderId(x.orderId);
return cnt <= 0;
});