Foreach并在C#

时间:2018-05-03 14:53:28

标签: c# .net performance linq iteration

我的代码中存在性能问题。

以下方法用于根据一些规则创建来自全国的公司的比较分数:

public List<object> GetCNAEBRCycleChart(int VisitId)
    {
        List<object> result = new List<object>();


        Visit visit = Context.Visit.Find(VisitId);
        Company company = visit.Company;
        var CNAE = company.MainEconomicCNAE.IdentifyCNAE;

        string[] Themes = new string[5];

        Themes[0] = "Finance";
        Themes[1] = "Market";
        Themes[2] = "Organization";
        Themes[3] = "Planning";
        Themes[4] = "People";

        int count = 0;

        List<Visit> listVisitCNAECountry = (from vis in Context.Visit
                                            where vis.Company.MainEconomicCNAE.IdentifyCNAE.StartsWith(CNAE)
                                                && vis.Order == 1
                                             select vis
                                                ).ToList();

        double[] Values = new double[5];

        Values[0] = 0;
        Values[1] = 0;
        Values[2] = 0;
        Values[3] = 0;
        Values[4] = 0;

        foreach (var vis in listVisitCNAECountry)
        {
            count = 0;
            var visitIdCompany = vis.Id;

            var diagnostic = Context.Visit.Find(visitIdCompany).Diagnostic;

            if (diagnostic != null)
            {
                foreach (var itemTheme in Themes)
                {
                    var TemaAux = itemTema;
                    int QtQuestion = (from itemForm in Context.FormItem
                                        join tipo in Context.FormItemType on itemForm.FormItemTypeId equals tipo.Id
                                        join itemForm2 in Context.FormItem on itemForm.FormItemParentId equals itemForm2.Id
                                        join itemForm3 in Context.FormItem on itemForm2.FormItemParentId equals itemForm3.Id
                                        where itemForm3.Name == TemaAux && tipo.Name == "Pergunta"
                                        select itemForm
                                              ).Count();

                    var sumAnswerCompany = (from alter in Context.Alternative
                                            join itemForm in Context.FormItem on alter.FormItemId equals itemForm.Id
                                            join itemForm2 in Context.FormItem on itemForm.FormItemParentId equals itemForm2.Id
                                            join itemForm3 in Context.FormItem on itemForm2.FormItemParentId equals itemForm3.Id
                                            join answer in Context.Answer on itemForm.Id equals answer.FormItemId
                                            where answer.AlternativeId == alter.Id &&
                                            answer.DiagnosticId == diagnostico.Id && itemForm3.Name == TemaAux

                                            select alter.Value
                                    ).AsEnumerable().Sum();

                    double scoreCompany = //Some calculations

                    Values[count] += scoreCompany;
                    count++;
                }
            }
        }

        count = 0;

        foreach (var val in Values)
        {
            Values[count] = //more calculations
            count++;
        }

        var model = new { NameCategory = "CNAE in Country", Value1 = Values[0], Value2 = Values[1], Value3 = Values[2], Value4 = Values[3], Value5 = Values[4] };

        result.Add(model);

        return result;
    }

问题在于,使用实际的CNAE,列表listVisitCNAECountry获得了16000多个元素,这会导致糟糕的性能。

在我的本地主机环境中,它需要30分钟+,我甚至不知道从哪里开始实际提高性能。

最大的问题是我真的需要所有这些迭代才能使计算正确。

如果有人有任何想法,请帮助我。

1 个答案:

答案 0 :(得分:3)

要改变的第一件事是:

                var sumAnswerCompany = ( /* complex query */
                                ).AsEnumerable().Sum();

这很糟糕;而不是将select sum(...)作为数据库查询发出,而是必须选择列并返回所需的所有行,这可能是巨大的带宽量。

相反,在数据库中执行总结并返回一个数字:

                var sumAnswerCompany = ( /* complex query */
                                ).Sum();

但是,坦率地说,我建议使用原始数据中的连接和分组在原始SQL中编写整个内容。有时候LINQ不是你最好的工具。