C# 提高linq查询的性能

C# 提高linq查询的性能,c#,performance,linq,C#,Performance,Linq,我正在使用大量Linq查询优化一个方法。到目前为止,执行时间大约是3秒,我正在努力减少它。在这个方法中有相当多的操作和计算,但是没有什么太复杂 我将非常感谢任何关于如何提高性能和优化代码的建议和想法 该方法的全部代码(下面我将指出延迟最大的地方): TeilnehmendeBetriebe有800多条生产线,其中TeilnahmeStatus地产通常有4项左右。所以,最大800*4次迭代,这毕竟不是一个很大的数字 因此,我主要参与优化这些行,希望将执行时间减少到半秒左右 我尝试的是: 将Lin

我正在使用大量Linq查询优化一个方法。到目前为止,执行时间大约是3秒,我正在努力减少它。在这个方法中有相当多的操作和计算,但是没有什么太复杂

我将非常感谢任何关于如何提高性能和优化代码的建议和想法


该方法的全部代码(下面我将指出延迟最大的地方):

TeilnehmendeBetriebe有800多条生产线,其中TeilnahmeStatus地产通常有4项左右。所以,最大800*4次迭代,这毕竟不是一个很大的数字

因此,我主要参与优化这些行,希望将执行时间减少到半秒左右

我尝试的是:

  • 将Linq改写为foreach:没有帮助,同时。。。也许并不奇怪,但值得一试

    foreach (var tb in teilnehmendeBetriebe) //836 items
    {
        foreach (var ts in tb.TeilnahmeStatus) //3377 items
        {
            if (ts.KomfortaktionId == komfortaktion.Id && ts.AktionsTypeId == 1)
            {
                testResult.Add(tb);
                break;
            }
        }
    }
    
  • 使用.Select()为teilnehmendeBetriebe选择特定列。也没用

  • 这对我尝试过的其他小操作都没有帮助

    有趣的是,foreach的第一次迭代可能需要2秒钟,第二次和以后的迭代只需要几毫秒,因此.net能够优化或重用计算数据

    欢迎您提供任何关于可以更改哪些内容以提高性能的建议

    编辑:
    teilnahmebetriebkomfortakation.TeilnahmeStatus
    被急切地加载到方法
    GetTeilnehmendeBetriebe

        public List<TeilnahmeBetriebKomfortaktion> GetTeilnehmendeBetriebe(Connection ctx, HashSet<Guid?> gruppen)
        {
            return ctx.TeilnahmeBetriebKomfortaktion.Include(
                                            c => c.TeilnahmeStatus).ToList();
        }
    
    public List GetTeilnehmendeBetriebe(连接ctx,HashSet-gruppen)
    {
    返回ctx.teilnahmebetriebkomfortakation.Include(
    c=>c.TeilnahmeStatus).ToList();
    }
    
    编辑2: 执行GetTeilnehmendeBetriebe时发送的查询为:

        SELECT 
        [Extent1].[Id] AS [Id], 
        [Extent1].[BetriebId] AS [BetriebId], 
        [Extent1].[MandantenId] AS [MandantenId], 
        [Extent1].[CreatedUser] AS [CreatedUser], 
        [Extent1].[UpdatedUser] AS [UpdatedUser], 
        [Extent1].[CreatedDate] AS [CreatedDate], 
        [Extent1].[UpdatedDate] AS [UpdatedDate], 
        [Extent1].[IsDeleted] AS [IsDeleted]
        FROM [Semas].[TeilnahmeBetriebKomfortaktion] AS [Extent1]
        WHERE [Extent1].[IsDeleted] <> cast(1 as bit)
    
    选择
    [Extent1].[Id]作为[Id],
    [extend1][BetriebId]作为[BetriebId],
    [Extent1]。[MandantenId]作为[MandantenId],
    [Extent1]。[CreatedUser]作为[CreatedUser],
    [Extent1]。[UpdateUser]作为[UpdateUser],
    [Extent1]。[CreatedDate]作为[CreatedDate],
    [Extent1]。[UpdateDate]作为[UpdateDate],
    [extend1][IsDeleted]作为[IsDeleted]
    从[Semas].[Teilnahmebetriebkomfortakation]AS[Extent1]
    其中[Extent1][IsDeleted]强制转换(1为位)
    
    我的假设是
    teilnahmebetriebkomfortakation.TeilnahmeStatus
    是一个延迟加载的集合,导致。您应该急切地获取该集合以提高性能


    foreach循环的以下迭代速度很快,因为在第一次迭代之后,这些对象不再从数据库服务器请求,而是从内存请求服务器。

    我们在这里讨论的是LINQ到实体吗?
    repoKomfortaktion.gettelinehmendebetriebe
    返回什么类型?@Daniel是的,Linq返回实体。它返回列表。如果您向我们显示
    CTX.Komfortaktionen
    查询,可能会有所帮助。“实体框架支持延迟加载相关实体。在实体框架运行时中,ObjectContext实例中LazyLoadingEnabled属性的默认值为false。但是,如果您使用实体框架工具创建新模型和相应的生成类,LazyLoadingEnabled在对象上下文的构造函数中设置为true。“-Idea非常好!但是,不幸的是,它已经提前加载了..(我在问题描述的末尾添加了这些详细信息)@Anelook:嗯……你能检查一下到底发送到服务器的是什么查询吗?我检查了发送的查询。事实上,我看不到TeilnahmeStatus连接到了哪里。我在问题描述中添加了查询。我相信问题确实与检索TeilnahmeStatus的方式有关。
        public List<TeilnahmeBetriebKomfortaktion> GetTeilnehmendeBetriebe(Connection ctx, HashSet<Guid?> gruppen)
        {
            return ctx.TeilnahmeBetriebKomfortaktion.Include(
                                            c => c.TeilnahmeStatus).ToList();
        }
    
        SELECT 
        [Extent1].[Id] AS [Id], 
        [Extent1].[BetriebId] AS [BetriebId], 
        [Extent1].[MandantenId] AS [MandantenId], 
        [Extent1].[CreatedUser] AS [CreatedUser], 
        [Extent1].[UpdatedUser] AS [UpdatedUser], 
        [Extent1].[CreatedDate] AS [CreatedDate], 
        [Extent1].[UpdatedDate] AS [UpdatedDate], 
        [Extent1].[IsDeleted] AS [IsDeleted]
        FROM [Semas].[TeilnahmeBetriebKomfortaktion] AS [Extent1]
        WHERE [Extent1].[IsDeleted] <> cast(1 as bit)