2

我的应用程序中有一些层。这些层遵循这样的结构:公司有定居点,定居点有部门,部门有机器,机器正在生产物品,机器需要工具来生产物品,......在这个层次结构的最末端有条目有多少物品可以用工具的特定部分(称为切割工具)生产。基于此,可以计算统计量。在每一层上,都会添加下一层的统计结果。看看这张图: 在此处输入图像描述

在每一层上,都会显示一个统计信息。例如:用户导航到第二层(项目)。有10个项目。用户可以看到显示每个项目成本的饼图。这些成本是通过添加项目工具(下一层)的所有成本来计算的。工具的成本是通过将“工具的一部分”的所有成本相加来计算的……我知道这有点复杂,所以如果有任何问题,请向我询问更详细的解释。

现在我的问题:要计算一个项目的成本(为机器、工具、... => 图表上的每一层提供相同的统计数据),我需要获取该项目的所有生命周期。所以我使用递归调用来跳过项目和生命周期之间的所有层。这工作得很好,但我使用了很多 SelectMany-linq 命令。结果,性能极差。我已经考虑过连接或过程(存储在数据库中)来加快速度,但到目前为止我还没有体验过哪些技术像数据库。所以我想问你,你会怎么做?目前我正在使用类似的东西:

public IEnumerable<IHierachyEntity> GetLifetimes(IEnumerable<IHierachyEntity> entities)
{
    if(entities is IEnumerable<Lifetime>)
    {
        return entities;
    }
    else
    {
        return GetLifetimes(entities.SelectMany(x => x.Childs))
    }
}
4

2 回答 2

1

由于这可能是您应用程序核心中相当固定的层次结构,因此我不介意为它编写一段专用代码。此外,使用 LINQ to a database backend 为分层查询编写有效的通用例程是不可能的。这个n+1问题是无法避免的。

所以只要做这样的事情:

public IQueryable<Lifetime> GetLifetimes<T>(IQueryable<T> entities)
{
    var machines = entities as IQueryable<Machine>;
    if (machines != null)
        return machines.SelectMany (m => m.Items)
                       .SelectMany (i => i.Tools)
                       .SelectMany (i => i.Parts)
                       .SelectMany (i => i.Lifetimes);

    var items = entities as IQueryable<Item>;
    if (items != null)
        return items.SelectMany (i => i.Tools)
                    .SelectMany (i => i.Parts)
                    .SelectMany (i => i.Lifetimes);

    var tools = entities as IQueryable<Tool>;
    if (tools != null)
        return tools.SelectMany (i => i.Parts)
                    .SelectMany (i => i.Lifetimes);

    var parts = entities as IQueryable<Part>;
    if (parts != null)
        return parts.SelectMany (i => i.Lifetimes);

    return Enumerable.Empty<Lifetime>().AsQueryable();
}

重复代码,是的,但它非常清楚发生了什么,它可能是代码中最稳定的部分之一。当需要持续维护时,重复代码是一个潜在的问题。

于 2013-11-10T19:47:49.340 回答
1

As much as I understood you trying to pull very long history of your actions. I need create a routine which will update your statistics as changes happened. This has no "ultimate" solution your should figure it out. E.g. I have "in" and "out" stock transactions and to find out current stock level for all items I should go through 20 years history. To come around I can do monthly summaries and only calculate changes from month start. Or I can use a database trigger to update my summaries as soon as changes happened (could be performance costly one). Or I can have a service that will update it time to time ( would not be 100% up to date possibly). In another words you need table/class which will keep your aggregated results ready to use.

于 2013-11-10T16:33:07.060 回答