gpt4 book ai didi

c# - 提高 LINQ 枚举器内条件查询的性能

转载 作者:太空宇宙 更新时间:2023-11-03 11:15:32 24 4
gpt4 key购买 nike

我有一些代码看起来像这样,使用 .NET 3.5(客户要求):

void Process (ActionState state)
{
var orderItemQuery = from OrderItem item in order.OrderItems
orderby item.OrderLineNumber ascending
select item;

foreach (OrderItem item in orderItemQuery)
{
ActionData actionData;
switch (state)
{
case ActionState.Prepare:
actionData = (
from ActionData ad in db.ActionDataTable
where ad.ObjectId == item.ProductId
select ad
).First();

case ActionState.QualityCheck:
actionData = (
from ActionData ad in db.ActionDataTable
where ad.ObjectId == item.OrderItemId
select ad
).First();

default:
throw new InvalidOperationException();
}

// ...
}
}

基本上第一个查询的结果是迭代的,一个特定的外键用于根据当前的 ActionState 从数据库中获取一个 ActionData 记录。实际上,这里那里有更多的嵌套和一些检查,但本质上是一样的。

这最初对测试数据库非常有效,但一位客户刚刚向我发送了一份他们的实时数据副本,速度慢得可怕。运行整个批处理大约需要 15 分钟,包括一些其他处理。通过性能测试器运行代码后,我发现整个过程中最慢的部分是对每种情况的 .First() 调用。

如果这是纯 SQL,我会根据 state 的值在循环外编译一个存储过程,然后使用它。既然我做不到,那有什么选择呢?我怎样才能加快速度?

最佳答案

您的问题是您的代码对数据库执行了 100500 次请求。你需要在一个请求中得到你想要的。为此,您需要编写正确的 linq 查询。像这样:

if(state!=ActionState.Prepare&&state!=ActionState.QualityCheck)
throw new InvalidOperationException();
var orderSelector = state == ActionState.Prepare
?o=>o.ProductId
:?o=>o.OrderItemId
var orderWithActionQuery = order.OrderItems.Orderby(o => o.OrderLineNumber).GroupJoin(
db.ActionDataTable,
orderSelector,
ad => ad.ObjectId,
(x, y) => new { item = x, actionDatas = y })
.Select(c => new {item = c.item, actionData = c.actionDatas.FirstOrDefault()});
foreach(var orderWithActionData in orderWithActionQuery)
{
//orderWithActionData.item is orderItem
//orderWithActionData.actionData is ation data of this item
}

在此代码中,对数据库的请求将与 foreach 一起发送。它将是单个请求并且性能会很好

关于c# - 提高 LINQ 枚举器内条件查询的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12802221/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com